[dmd-beta] rvalue references

Andrei Alexandrescu andrei at erdani.com
Tue Apr 10 21:33:11 PDT 2012


On 4/10/12 7:57 PM, Walter Bright wrote:
> 2.
> double& d;
> int i;
> void foo() {
> d = i;
> }

This example is off; a reference can't be rebound. The relevant example is:

void increment(double& d)
{
     ++d;
}
...
int i;
increment(i);

People think the int has been incremented, but in fact a useless 
temporary has.

The discussion about what to do in D has been a bit longer and more 
far-reaching than Walter mentioned.

The long-term plan is to never let the address of a ref escape the 
expression in which the ref occurs. That means in essence that user code 
can't take the address of a ref.

Once that is in place, we will know for sure that all ref passed into 
and returned by functions will not escape the immediate expression in 
which that happens - great for safe code.

People who need to take &this and escape it (e.g in linked lists 
implemented with struct) will not be able to; they'll have to use static 
functions and pointers for that. Generally any work that involves 
escaping pointers will have to use pointers, not references.

I think this puts us in a very good spot:

1. Safe code will be able to use ref liberally

2. Functions will be able to return ref knowing the ref won't survive 
the current expression. This is awesome for sealed containers - safe and 
fast.

What does this have to do with rvalues and lvalues? It means that with 
the appropriate precautions, we _can_ transform rvalues into lvalues, 
because we know their address can't unsafely escape.

There is one precautions to take: we should never convert a value of 
type T to a ref of another type U. That would cause the problems we 
learned from C++. There are 3 cases of such implicit conversions:

1. built-in numerics, e.g. an int should not convert to a ref double.

2. Class inheritance, e.g. a Widget should not convert to a ref Object.

3. alias this, e.g.:

struct T {}
struct A { @property T fun(); alias fun this; }
void fun(ref T);
...
A a;
fun(a); // should not work


I think this all holds water. Destroy!

Andrei



More information about the dmd-beta mailing list