Previous section   Next section

Imperfect C++ Practical Solutions for Real-Life Programming
By Matthew Wilson
Table of Contents


Part Two: Surviving the Real World

As is the case with C, C++ leaves the definition of a great many of its features open. In the parlance of the standard (C++-98: 1.3), a conformant implementation may have features that are implementation-defined, or are unspecified. Both of these terms mean that such features can be implemented as the compiler vendor deems fit and/or the operating environment mandates. The difference between them is that implementation-defined behavior has to be documented, whereas unspecified behavior does not. For the sake of clarity, I'm going to refer to all of this as implementation defined, since there are precious few unspecified things that you genuinely will not care about. Note that this is quite different from undefined behavior, which customarily means a nasty crash in full view of management.

In some cases there are valid reasons for the freedom of implementation; in others, the language has failed to adequately address modern techniques. In either case, these issues can cause huge headaches in the real world of C++ programming.

What we will see throughout much of the book are imperfections, techniques, and strategies that largely pertain to individual source files or to individual classes. However, the chapters in this part cover matters that pertain to whole programs, consisting of multiple source files and, potentially, binary components. The programs have to interface with their operating environment in a safe and predictable fashion, and, in some cases, have to be robust in the presence of other processes or threads of execution.

Hence, these chapters address some of the most significant imperfections in C++. It's not that there aren't techniques for dealing with the imperfections—there are—rather, the failure to handle the imperfections can have very serious ramifications, and the techniques themselves can be both difficult to understand and difficult to apply. It is in these areas that critics of the language acquire much of their ammunition.

Although these issues are notionally separate, they all tend to affect each other, so I would recommend that you read the chapters in order, and keep in mind that some issues may not be fully addressed until a later chapter.

We start with a discussion about the lack of a binary standard for C++ component interaction, which places serious constraints on the development of large systems and severely limits the ability to provide reusable software components in C++. Next, the issue of providing polymorphic behavior in a compiler-independent fashion is examined, including a discussion of the object layout strategies taken by several compilers and techniques for obviating these differences.

The use of dynamic linking to build executables for modern operating systems is also not addressed by C++, and complicates the experience of most practitioners. Similarly, multithreading is a big area in which C++ proves to be deficient, and in fact it provides virtually no support for this popular and powerful technique. These two issues form the next two chapters.

Then the issue of static objects is discussed, illustrating the problems encountered when using both local statics and nonlocal statics. Though the two are closely related, there are some significant differences, particularly when one considers multithreading and multimodule development.

After spending time showing things that are seriously wrong with the language, we finish with a bit of informative light relief and a look at optimization; what compilers take away (often without asking).

There are six chapters: Chapter 7, ABI; Chapter 8, Objects across Borders; Chapter 9, Dynamic Libraries; Chapter 10, Threading; Chapter 11, Statics; and Chapter 12, Optimization. Naturally one part of one book cannot hope to provide a complete picture of all the issues involved, but I hope that this will help you be better prepared when you encounter these imperfections in your work.

After Part One, I expect you came out with a warm, happy sensation, seeing C++ in an almost entirely positive light. You'll need to hold on to those feelings as you read this part (and the next), as we'll be giving the old girl a bit of a savaging. Several of the issues highlighted are those where C++ does not generally distinguish itself well with respect to other languages. The upside is that there are practical answers to most of the problems highlighted.



      Previous section   Next section