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.
_______________________________________________
dmd-beta mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/dmd-beta

Reply via email to