Previous Table of Contents Next


6.2.4.1. Runtime Efficiency

In Simula, it is not possible to have local or global variables of class types; that is, every object of a class must be allocated on the free store using the new operator. Measurements of my Cambridge simulator had convinced me that this was a major source of inefficiency. Later, Karel Babcisky (1984) from the Norwegian Computer Centre presented data on Simula runtime performance that confirmed my conjecture. For that reason alone, I wanted global and local variables of class types.

In addition, having different rules for the creation and scope of built-in and user-defined types is inelegant, and I felt that on occasion, my programming style had been cramped by absence of local and global class variables in Simula. Similarly, I had on occasion missed the ability to have pointers to built-in types in Simula, so I wanted the C notion of pointers to apply uniformly over user-defined and built-in types. This is the origin of the notion that over the years grew into a principle for C++: User-defined and built-in types should behave the same relative to the language rules and receive the same degree of support from the language and its associated tools. When the ideal was formulated, built-in types received by far the best support, but C++ has overshot that target so that built-in types now receive slightly inferior support compared to user-defined types.

The initial version of C with Classes did not provide inline functions to take further advantage of the availability of the representation. Inline functions were soon provided, though. The general reason for the introduction of inline functions was concern that the cost of crossing a protection barrier would cause people to refrain from using classes to hide representation. In particular, Adding Classes to the C Language: An Exercise in Language Evolution observes that people had made data members public to avoid the function call overhead incurred by a constructor for simple classes where only one or two assignments are needed for initialization. The immediate cause for the inclusion of inline functions into C with Classes was a project that couldn’t afford function call overhead for some classes involved in real-time processing.

Over the years, considerations along these lines grew into the C++ principle that it was not sufficient to provide a feature; it had to be provided in an affordable form. Most definitely, affordable was seen as meaning “affordable on hardware common among developers” as opposed to “affordable to researchers with high-end equipment” or “affordable in a couple years when hardware is cheaper.” C with Classes was always considered something to be used now or next month rather than simply a research project to deliver something a couple of years hence.

Inlining was considered important for the utility of classes, and therefore the issue was more how to provide it than whether to provide it. Two arguments won the day for the notion of having the programmer select which functions the compiler should try to inline. First, I had poor experiences with languages that left the job of inlining to compilers “because clearly the compiler knows best.” The compiler knows best only if it has been programmed to inline and it has a notion of time and space optimization that agrees with mine. My experience with other languages was that only “the next release” would actually inline, and it would do so according to an internal logic that a programmer couldn’t effectively control. To make matters worse, C (and therefore C with Classes and later C++) has genuine separate compilation so that a compiler never has access to more than a small part of the program (section 6.2.4.2). Inlining a function for which you don’t know the source appears feasible given advanced linker and optimizer technology, but such technology wasn’t available at the time (10 years later, it still wasn’t in most environments). Furthermore, extensive global analysis and optimization easily become unaffordable for large systems—where optimizations are most critical. C with Classes was designed to deliver efficient code given a simple portable implementation on traditional systems. Given that, the programmer had to help. Even today, the choice seems right.

6.2.4.2. The Linkage Model

The issue of how separately compiled programs are linked together is critical for any programming language and to some extent determines the features the language can provide. One of the critical influences on the development of C with Classes and C++ was the decision that

  Separate compilation should be possible with traditional C/Fortran UNIX/DOS style linkers.
  In principle, linkage should be type safe.
  Linkage should not require any form of database (although one could be used to improve a given implementation).
  Linkage to program fragments written in other languages such as C, assembler, and Fortran should be easy and efficient.

C uses header files to ensure consistent separate compilation. Declarations of data structure layouts, functions, variables, and constants are placed in header files that typically are textually included into every source file that needs the declarations. Consistency is ensured by placing adequate information in the header files and ensuring that the header files are consistently included. C++ follows this model up to a point.

The reason that layout information can be present in a C++ class declaration (although it doesn’t have to be; see section 6.4.3) is to ensure that the declaration and use of true local variables are easy and efficient. Here’s an example:

   void f()
   {
       stack s;
       int c;
       s.push(‘h’);
       c = s.pop();
   }

Using the stack declaration from section 6.2.4, even a simplistic C with Classes implementation can ensure that no use is made of free store for this example, that the call of pop() is inlined so that no function call overhead is incurred, and that the non-inlined call of push() can invoke a separately compiled function pop(). In this, C++ resembles Ada (Ichbiah, 1979).


Previous Table of Contents Next