Previous section   Next section

Imperfect C++ Practical Solutions for Real-Life Programming
By Matthew Wilson
Table of Contents
Chapter 8.  Objects Across Borders


8.3. ABI/OAB Coda

I'd now like to revisit the imperfection from Chapter 7 and rephrase it. I hope there's no ambiguity in the message from most of this book that C++ is a superb language in many respects, and it is almost always my first choice for the implementation of libraries. But for codifying the interfaces between binary modules, especially between dynamically linked modules, it is just not up to the task.

Imperfection: C++ is not a suitable module-interface language.


It's not possible here to go through the full gamut of problems I've encountered when trying to use mangling across borders, but I am comprehensively convinced through my own experiences, and those of many clients, that C++ is not an appropriate module-interface language. We'll see more ramifications of this in other chapters in this part.

I won't try to pretend for a second that the techniques described are trivial to use. They require a degree of effort, and one must accept serious constraints. I've not gone into them all here because we'll be discussing them in forthcoming chapters as they pertain to other techniques in C++, as well as making an ABI.

Nor can I claim that they represent a full ABI by any stretch of the imagination. For example, you cannot use multiple or virtual inheritance, cannot throw exceptions through ABI barriers, or directly delete objects acquired through them. If you're writing code that needs to work only with other code written by the same compiler vendor (and version, as that can often need to remain constant), then you're best off not buying into these techniques.

There are efforts in the industry to support the full range of C++ language facilities [Itan-ABI], but they are neither mature nor broadly applicable. What I have presented is a useful and broadly applicable technique that, although constraining, can be used on a wide variety of existing compilers and operating systems.

But don't let the constraints and complexities make you think that this is nothing but a theoretical solution that couldn't be practically applied; nothing could be further from the truth. Once the infrastructure is set up, using such systems is easy and straightforward.[8]

[8] I've used it to good effect in the Arturius compiler multiplexer (see Appendix C).

Indeed, the best example I have of the manifest usefulness for this technique was on a project I worked on a few years ago. I was brought in as a C++ specialist[9] on a project that had a little bit of time pressure. The development lead and I had to take a parsing system developed, over several years, for the U.S. market and apply it to the Australian market, and it had to be ready within a month. After one day on the existing system, we got a serious case of NIH (Not Invented Here syndrome), and started on a total rewrite. Three weeks later, we had an extensible parsing architecture, along with several Australia-specific parsing modules, that was working on Win32, Linux and UNIX (DEC Alpha). It was subsequently ported to several other operating systems, including Solaris and VMS. It was faster, and achieved higher levels of input data recognition, than any previous system for the company, and soon became their world standard.

[9] A specialist is a euphemism for an expert, and that's always a dangerous thing. I probably know twice as much about C++ now as I did then, and the more I learn the less (I realize) I know. In fact, you should probably put this book down now, and go read some Sutter!

The point of all this is not to regale you with one of my occasional successes but rather to assure you that the Objects across Borders approach is very powerful and widely applicable; it is not just useful for COM on Win32.

One last thing: there's no doubt that my perspective on this matter is colored by my own experience and prejudices. I am not a single-language person, and I relish working at the borders between one language and another.[10] I've done a lot of COM in the last decade, and I like many, though by no means all, aspects of that technology. Finally I am not a huge fan of exceptions,[11] and I can't remember the last time I used RTTI, so the absence of these mechanisms from the C++ ABI does not represent much of a loss to me. You will undoubtedly have different experiences, and may well have different views. If that's the case, then I hope that you can at least take from these two chapters a deeper understanding of the C++ object model, and ABI issues in general, even if you do not utilize these techniques in your own work.

[10] I write a column for C/C++ User's Journal called "Positive Integration" which is all about integrating C++ with other languages. (There are some installments included on the CD.)

[11] Don't get me wrong here. Exceptions are the absolute best mechanism for several problems in C++, such as constructor failure, out-of-memory conditions, and deep semantic processing such as parsing. I just think they're much overused in other circumstances.


      Previous section   Next section