Why are references not reseatable in C++
C++ references have two properties:
- They always point to the same object.
- They can not be 0.
Pointers are the opposite:
- They can point to different objects.
- They can be 0.
Why is there no "non-nullable, reseatable reference or pointer" in C++? I can't think of a good reason why references shouldn't be reseatable.
Edit: The question comes up often because I usually use references when I want to make sure that an "association" (I'm avoiding the words "reference" or "pointer" here) is never invalid.
I don't think I ever thought "great that this ref always refers to the same object". If references were reseatable, one could still get the current behavior like this:
int i = 3;
int& const j = i;
This is already legal C++, but meaningless.
I restate my question like this: "What was the rationale behind the 'a reference is the object' design? Why was it considered useful to have references always be the same object, instead of only when declared as const?"
Cheers, Felix
The reason that C++ does not allow you to rebind references is given in Stroustrup's "Design and Evolution of C++" :
It is not possible to change what a reference refers to after initialization. That is, once a C++ reference is initialized it cannot be made to refer to a different object later; it cannot be re-bound. I had in the past been bitten by Algol68 references where
r1=r2
can either assign throughr1
to the object referred to or assign a new reference value tor1
(re-bindingr1
) depending on the type ofr2
. I wanted to avoid such problems in C++.
In C++, it is often said that "the reference is the object". In one sense, it is true: though references are handled as pointers when the source code is compiled, the reference is intended to signify an object that is not copied when a function is called. Since references are not directly addressable (for example, references have no address, & returns the address of the object), it would not semantically make sense to reassign them. Moreover, C++ already has pointers, which handles the semantics of re-setting.
Because then you'd have no reseatable type which can not be 0. Unless, you included 3 types of references/pointers. Which would just complicate the language for very little gain (And then why not add the 4th type too? Non-reseatable reference which can be 0?)
A better question may be, why would you want references to be reseatable? If they were, that would make them less useful in a lot of situations. It would make it harder for the compiler to do alias analysis.
It seems that the main reason references in Java or C# are reseatable is because they do the work of pointers. They point to objects. They are not aliases for an object.
What should the effect of the following be?
int i = 42;
int& j = i;
j = 43;
In C++ today, with non-reseatable references, it is simple. j is an alias for i, and i ends up with the value 43.
If references had been reseatable, then the third line would bind the reference j to a different value. It would no longer alias i, but instead the integer literal 43 (which isn't valid, of course). Or perhaps a simpler (or at least syntactically valid) example:
int i = 42;
int k = 43;
int& j = i;
j = k;
With reseatable references. j would point to k after evaluating this code. With C++'s non-reseatable references, j still points to i, and i is assigned the value 43.
Making references reseatable changes the semantics of the language. The reference can no longer be an alias for another variable. Instead it becomes a separate type of value, with its own assignment operator. And then one of the most common usages of references would be impossible. And nothing would be gained in exchange. The newly gained functionality for references already existed in the form of pointers. So now we'd have two ways to do the same thing, and no way to do what references in the current C++ language do.