[dmd-beta] rvalue references
Walter Bright
walter at digitalmars.com
Tue Apr 10 17:57:01 PDT 2012
I couldn't remember what the big problem was with rvalue references, and so I
spent some time on the phone talking with Andrei about what exactly the problem
is. They are:
1.
C++:
int i;
double& d = i;
++d;
The problem is that i is implicitly converted to a double, and then the address
is taken and assigned to d. When what d refers to is incremented, it increments
the temporary, and i is inexplicably left untouched. I say inexplicably because
when an implicit conversion happens isn't always obvious to the user. C++ is
full of implicit conversions, so these types of silent bugs crop up.
This one isn't too bad, you could say "just make it a const&", but consider the
related:
2.
double& d;
int i;
void foo() {
d = i;
}
Now d is referring to a temporary that has gone out of scope. This is, of
course, a memory corrupting disaster, const ref or no const.
3. This one is a more general problem with references, that of escaping
references to locals:
double& d;
void foo(double x, double y) {
d = x + y;
}
OMG LOL big oops, we've now got a reference to a temporary that goes out of scope.
---------------------------------------------
Our D solution, disallowing rvalue references, is technically sound but as we've
discussed here is a usability disaster, and auto ref isn't going to cut it. We
figured a solution is:
*** Allow rvalue references, however, disallow any implicit conversions of the
literal's type in the process of taking a reference to it. ***
That takes care of 1 and 2. The solution to 3 is a bit more subtle. Some people
have wondered why the D compiler can create reference types itself, but does not
allow the user to outside of function parameters and foreach variables. This is
the reason why. References, in order to be safe, must not be allowed to escape a
scope. They can only be passed downward to enclosed scopes, and returned from
functions where the return value is checked. Also, one cannot take the address
of a reference. I think this closes the holes.
With all that, I intend to once again allow struct literals to be lvalues for
2.059. Somewhat later, also allow references to other literals like 0 and 5.6.
More information about the dmd-beta
mailing list