Previous | Table of Contents | Next |
With one exception, this chapter discusses only pitfalls that are in C++ and not also in C. The reasons is that in 1988, I wrote a book called C Traps and Pitfalls (Koenig, 1989) that summarized what I had learned until then about C pitfalls. Its coverage includes
Although most C pitfalls appear in C++ as well, they are less important in C++ than they are in C. The reason is that C++ makes it easier to define classes that represent high-level abstractions; these abstractions often make it possible to avoid the C pitfalls entirely. For example, the standard C++ library provides a flexible vector class that avoids many of the pitfalls associated with C arrays, and inline functions in C++ make the C preprocessor, with its attendant pitfalls, much less important.
The one C pitfall that this chapter discusses is the notion of const as part of a type. At the time that C Traps and Pitfalls was published, the C standardization effort, already under way, had incorporated the idea of const into C from C++. However, it would be some time before the idea made it into C compilers and thence into widespread practice. There was therefore not enough user experience to know where the pitfalls were. The complexities of using const in C++ declarations therefore appear in this chapter, even though most of those complexities are present in C as well.
The point of this chapter is to give a programmer who already understands how to use C, and how to avoid its pitfalls, a feel for what kinds of hazards are particularly important to learn to avoid in C++. Although such hazards are intrinsically hard to classify, the chapter divides them into three broad categories. The boundary between the second and third category is slightly fuzzy.
The first area is syntax, which I discuss in section 8.2. Which syntactic aspects cause trouble in a language are largely a matter of taste and prior experience. C++ syntax is closely related to C syntax, so C programmers will find many parts of it familiar. Nevertheless, some parts of C++ syntax seem to cause trouble fairly regularly and are definitely worth mentioning.
Section 8.3 covers static semantics, particularly in the area of types. C++ is a compromise between the desire for the safety and efficiency of compile-time type checking and the desire for the flexibility and expressive power of dynamically varying types. Such compromises are bound to cause problems once in a while, and again some of those problems are worth pointing out.
Finally, in section 8.4, we discuss ways in which programs can go astray during execution, despite the programmers and compilers efforts to avoid trouble.
This chapter is not intended to be exhaustive. Instead, it presents a few important examples in each area, in an effort to give an understanding of what the problems are, why they exist, and how to learn to avoid them.
C++ inherits much of its syntax from C. It also inherits Cs desire to keep the number of keywords, and other syntactic constructs, relatively small. As a result, C++ programs tend to be syntactically terse, and the language often gives several different meanings to a symbol, depending on the context.
For example, colons are part of labels both in C and in C++. In C++, however, colons are also used to indicate inheritance and to delimit constructor initializers. Moreover, C++ widens the syntactic contexts for labels to include class declarations.
The rest of this section gives examples of C++ syntax that beginners find particularly troublesome.
Previous | Table of Contents | Next |