Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ames!apple!rutgers!att!ulysses!andante!alice!bs From: bs@alice.UUCP (Bjarne Stroustrup) Newsgroups: comp.lang.c++ Subject: Re: C++ design Summary: efficiency Keywords: information Message-ID: <9477@alice.UUCP> Date: 13 Jun 89 19:43:06 GMT References: <9474@alice.UUCP> Organization: AT&T Bell Laboratories, Murray Hill NJ Lines: 50 Part of C++'s complexity comes from its abilility to deal with objects directly. In most `object-oriented language', including Simula and Eiffel (I believe), an object of a class must be allocated on the free store and manipulated through a pointer (an implicit pointer, in the case of Eiffel). This has several effects, some beneficial, some not. The beneficial effects of dealing with object only through pointers, such as minimal recompilation after changes to the class declaration, can be achieved in C++ for specific classes by NOT allocating static, automatic, or member objects of those classes and avoiding the use of inlines for their functions. Tools, such as compilers and programs calculating minimal recompilation must be alert to these possibilities. Not having automatic, static, and member objects (as in Simula, Smalltalk, etc.) have an obvious cost in allocation and deallocation. It also implies a storage overhead of a pointer per object and a run-time overhead of at least one memory reference per access to such an object. In presentation to IFIP WG2.4 in 1984 Karel Babcicky estimated the cost of NOT having static and automatic objects of class types in Simula to a factor of two in run-time. His estimate was based on measurements of Simula programs. Karel was in charge of Simula maintenance for the Norvegian computing center for 10 years. The absense of automatic, static, and member objects simplifies garbage collection but also causes a greater need for it. Having member objects in C++ (rather than simply having an object be a set of pointers to sub-objects implies a nice compact storage layout and a minimal storage allocation de-allocation overhead. It is easy to underestimate the effects of these `little' differences in raw (i.e. low-level) efficiency and deficiencies in these areas may be alleviated by gains in overall program organization. However, I have seen no evidence for systematic compensatory gains of this kind compared to C++ in other languages and the absense of low-level run-time efficiency and data compactness definitely leads to C, assembler, and Fortran use. People who refer to C++ as `an object-oriented assembler' often miss the point. C++ is - among other things - really meant fit that description. It was designed to be able to fill that role too. Allocation of objects on the free store can lead not only to inefficiency, but also - in languages where the inderiction is implicit - to a noticeably `discontinuity' in the semantics of assignment. Built in types have copy semantics (e.g. a = b gives `a' the value of `b' if `a' and `b' are, say, ints) whereas user-defined types have pointer semantics (e.g. a = b makes `a' refer to the same object as `b' - not a copy of that object - if `a' and `b' are, say, complex variables). In C++ copy semantics is used for both built-in and user-defined types. Pointer semantics for user-defined types can be implemented by overloading the assignment operator.