Previous | Table of Contents | Next |
6.3.3.4. C++ References
References were introduced primarily to support operator overloading. C passes every function argument by value, and where passing an object by value would be inefficient or inappropriate, the user can pass a pointer. This strategy doesnt work where operator overloading is used. In that case, notational convenience is essential so that a user cannot be expected to insert address-of operators if the objects are large.
Problems with debugging Algol68 convinced me that having references that didnt change what object they referred to after initialization was a good thing. If you want to do more complicated pointer manipulation in C++, you can use pointers. Because C++ has both pointers and references, it does not need operations for distinguishing operations on the reference itself from operations on the object referred to (like Simula) or the kind of deductive mechanism employed by Algol68.
It is important that const references can be initialized by both non-lvalues and lvalues of types that require conversion. In particular, this is what allows a Fortran function to be called with a constant:
extern Fortran float sqrt(const float&); // & means reference void f() { // ... sqrt(2); // call by reference // ... }
Jonathan Shopiro was deeply involved in the discussions that led to the introduction of references. In addition to the obvious uses of references, such as argument, passing we considered the ability to use references as return types important. This allowed us to have a very simple index operator for a string class:
class String { // ... char& operator[](int index); // subscript operator; return a reference }; void f(String& s) { char c1 = ... s[i] = c1; // assign to operator[]s result // ... char c2 = s[i]; // assign operator[]s result }
We considered allowing separate functions for left-hand and right-hand side use of a function but considered using references the simpler alternative even though this implies that we need to introduce additional helper classes to solve some problems where returning a simple reference isnt enough. In retrospect, some way of defining separate functions for left-hand and right-hand side use would have been useful in many cases.
6.3.3.5. Constants (const)
In operating systems, it is common to have access to some piece of memory controlled directly or indirectly by two bits: one that indicates whether a user can write to it and one that indicates whether a user can read it. This idea seemed to me directly applicable to C++, and I considered allowing every type to be specified readonly or writeonly (Stroustrup, 1981a). The proposal was focused on specifying interfaces rather than on providing symbolic constants for C. Clearly, a readonly value is a symbolic constant, but the scope of the proposal was far greater. Initially, I proposed pointers to readonly but not readonly pointers. A brief discussion with Dennis Ritchie evolved the idea into the readonly/writeonly mechanism that I implemented and proposed to an internal Bell Labs C standards group chaired by Larry Rosler. There, I had my first experience with standards work. I came away from a meeting with an agreement (that is, a vote) that readonly would be introduced into Cyes C, not C with Classes or C++provided it was renamed const. Unfortunately, a vote isnt executable, so nothing happened to our C compilers. A while later, the ANSI C committee (X3J11) was formed, and the const proposal resurfaced there and became part of ANSI/ISO C.
In the meantime, however, I had experimented further with const in C with Classes and found that const was a useful alternative to macros for representing constants only if a global consts were implicitly local to their compilation unit. Only in that case could the compiler easily deduce that their value really didnt change and allow simple consts in constant evaluations and thus avoid allocating space for such constants and use them in constant expressions. C did not adopt this rule. This makes consts far less useful in C than in C++ and leaves C dependent on the preprocessor, whereas C++ programmers can use properly typed and scoped consts.
Previous | Table of Contents | Next |