Electronic Review of Computer Books

[ ERCB Home | New | Feature | Brief | DDJ | Letters | Links ]

[an error occurred while processing this directive]

Vital Statistics

Title Inside The C++ Object Model
Author Stanley B. Lippman
Publisher Addison-Wesley Longman
Reading, Massachusetts
http://www.awl.com/
Copyright 1996
ISBN 0-201-83454-5
Pages 280
Price $34.95


Understanding The True Semantics of C++

Stanley Lippman is a very popular name in the C++ community, in particular because the author of this book has also written the bestselling C++ Primer (now in its third edition), which I consider one of the best companions to Stroustrup's The C++ Programming Language, and because of his activity as the editor of the well-respected C++ Report magazine.

In this text, Stanley analyzes the language from a very different perspective compared to his other excellent book: The reader is supposed to possess a good working knowledge of C++ and have some real practical experience in his/her curriculum before approaching the first page. From this level s/he is taken to real mastery of the semantics of the complexities of the language, which reserves a lot of surprises and hidden dangers to even the most skilled engineers. Almost all of the fundamental building blocks are dissected, put in a historical perspective, and explained with precision in a surprisingly easy-to-follow way.

I am convinced that much of the clarity evident even in the most intrinsically complicated passages is due to the author's choice of giving very little for granted prior to starting a thorough discussion around a tough point. This manual will surely be of little help to a neophyte, but just as surely one needs not belong to a panel of experts to benefit from its observations, because the level of complexity never gets too deep without having spent some pages of prior accessible contextual information to get everyone up to speed.

Inside the C++ Object Model is aimed at those developers who routinely use C++ but feel the discomfort of not really knowing the underlying weight of many common operations they perform or constructs they peruse. A particularly fit subset of these programmers is made up of the hardcore plumbers who pay their bills writing C++-based programming tools and libraries, or those who assume the uneasy role of the "official code optimizer" in a medium-to-large development team. Each of these programmers are going to immensely appreciate the intensive coverage of the object-oriented features offered by the language, their run-time overhead (in terms of execution time and binary size), and their influence in compilation times. This knowledge constitutes a major aid when it comes time to decide whether a certain language feature fits your needs without breaking your requirements. Moreover, along the way the text is sprinkled with interesting anecdotes explaining why certain common myths regarding C++ are nothing more than unfounded rants.

The topics and comparisons filling up the chapters are always concrete and never exceedingly academic. For example, the old C-style data manipulation is compared side-by-side with the modern encapsulation methodologies promoted by OOP, which involves inline accessors and mutators. Another chapter deals with the tricky semantics of construction and destruction, dedicating a fair amount of room to the exact circumstances that trigger the execution of constructors, destructors, copy constructors, and conversion operators. This leads to the treatment of the delicate topic of the automatic creation of temporary variables by the compiler.

Moving on, of particular interest to me are the sections focusing on the cost of virtual functions (to achieve polymorphism) compared to static-bound methods, as well as the section discussing various facets of multiple inheritance.

There are very few aspects of this book that do not deserve praise. One of them, by far the least important, is the design, which I would have preferred to be more dynamic, thereby simplifying the jumps from one point to another (which makes sense considering the typology of the contents).

The real drawback of Inside The C++ Object Model is that it is dated. Most of what Stanley says still holds true and is informative, but the language has evolved a lot since its 1996 incarnation, when the manuscript was first sent to the printers. Consequently, many of the newer features, despite their undoubted load of semantic insights and potential misconceptions, are not even touched. Namespaces are entirely forgotten, and even such crucial relatively recent elements like exceptions, templates and run-time type information receive far less coverage than they deserve. Now that the ANSI/ISO C++ committee has agreed on a final standard, I really hope Lippman will decide to take the time to update and expand his already admirable work.

-- Davide Marcato (marcato@programmers.net or http://www.DavideMarcato.com)


Excerpts from Inside The C++ Object Model

Chapter 3 ("The Semantics of Data -- Access of a Data Member"), page 77

"The Standard requires within an access section (the private, public, or protected section of a class declaration) only that the members be set down such that "later members have higher addresses within a class object" (Section9.2 of the Standard). That is, the members are not required to be set down contiguously. What might intervene between the declared members? Alignment constraints on the type of a succeeding member may require padding. This is true both of C and C++, and in this case, the member layout of the two languages is in current practice the same.

"Additionally, the compiler may synthesize one or more additional internal data members in support of the Object Model. The vptr, for example, is one such synthesized data member that all current implementations insert within each object of a class containing one or more virtual functions..."

Chapter 4 ("The Semantics of Function -- Virtual Member Functions"), page 132

"The general rule is that the this pointer adjustment of a derived class virtual function invocation through a pointer (or reference) of a second or subsequent base class must be accomplished at runtime. That is, the size of the necessary offset and the code to add it to the this pointer must be tucked away somewhere by the compiler. The obvious first question is where?

"Bjarne's original cfront solution was to augment the virtual table to hold the (possibly) necessary this pointer adjustment. Each virtual table slot, rather than simply being a pointer, became an aggregate containing both the possible offset and the address. The virtual function call changed from:

(*pbase2->vptr[1])( pbase2 );

into

( *pbase2->vptr[1].faddr)( pbase2 + pbase2->vptr[1].offset );

where faddr held the virtual function address and offset held the necessary this pointer adjustment.

"The criticism of this solution is that it penalizes all virtual functions' invocations regardless of whether the offset adjustment is necessary, both in the cost of the extra access and addition of offset and in the increased size of each virtual table slot.

"The more efficient solution is to use a thunk. (When I first learned of the thunk, my professor jokingly told us that thunk is knuth spelled backwards and therefore he attributed the technique to Dr. Knuth.) First introduced in compiler technology, I believe, in support of ALGOL's unique pass-by-name semantics, the thunk is a small assembly stub that (a) adjusts the this pointer with the appropriate offset and then (b) jumps to the virtual function. For example, the thunk associated with the call of the Derived class destructor through a Base2 pointer might look ..."

Chapter 7 ("On the Cusp of the Object Model -- Templates"), page 239

"C++ programming styles and idioms have been profoundly transformed since the introduction of templates (with cfront, Release 3.0, in 1991) and experience using them. Originally viewed as a support for container classes such as Lists and Arrays, templates are now the foundation for generic programming (the Standard Template Library). They also are used as idioms for attribute mix-in where, for example, memory allocation strategies ([BOOCH93]) or mutual exclusion mechanisms for synchronizing threads ([SCHMIDT94]) are parameterized. They further are used as a technique for template metaprograms, in which class expression templates are evaluated at compile time rather than runtime, thereby providing significant performance improvements ([VELD95]).

"That said, however, it is also true that programming with template is currently one of the most frustrating aspects of C++ programming. Error messages are also generated far from the actual site of the problem. Compilation times often rise exponentially, and one begins to positively dread changing a header file with multifile dependencies, particularly if one is in the midst of debugging. It also isn't uncommon to find unexpected balooning of program size. Further, all these behaviors are generally beyond the comprehension of the average programmer who simply wants to get his or her work done and who, if these problems persist, may come to view the language more as an obstacle than as an aid. It is not uncommon to find a designated template expert among the members of a project who trouble-shoots and attempts to optimize the generation on templates..."


Table of Contents

Object Lessons

Layout Costs for Adding Encapsulation

The C++ Object Model

A Keyword Distinction

An Object Distinction

The Semantics of Constructors

Default Constructor Construction

Copy Constructor Construction

Program Transformation Semantics

Member Initialization List

The Semantics of Data

The Binding of a Data Member

Data Member Layout

Access of a Data Member

Inheritance and the Data Member

Object Member Efficiency

Pointer to Data Members

The Semantics of Function

Varieties of Member Invocation

Virtual Member Functions

Function Efficiency

Pointer-to-Member Functions

Inline Functions

Semantics of Construction, Destruction, and Copy

Object Construction without Inheritance

Object Construction under Inheritance

Object Copy Semantics

Object Efficiency

Semantics of Destruction

Runtime Semantics

Object Construction and Destruction

Operators new and delete

Temporary Objects

On the Cusp of the Object Model

Templates

Exception Handling

Runtime Type Identification

Efficient, but Inflexible

Index


Quick Rating

Readability Star Star Star HalfStar
Originality Star Star Star
Organization Star Star Star
Accuracy Star Star Star HalfStar
Consistency Star Star Star
Depth Star Star Star
Timeliness Star Star Star
Editing Star Star Star HalfStar
Design Star Star HalfStar
Overall Value Star Star Star HalfStar

Explanation of ERCB rating scale: No stars = unacceptable, 1 Star = marginal, 2 Stars = average, 3 Stars = above average, 4 Stars = exceptional.


Copyright ©1999 Electronic Review of Computer Books
Created 4/9/1999 / Last modified 4/9/1999 / webmaster@ercb.com