[dmd-beta] rvalue references

kenji hara k.hara.pg at gmail.com
Thu Apr 12 22:58:02 PDT 2012


I think to avoid some useless case, I'd like to add a rule.

In basic, literals (e.g. 10, 3.14, "hello") in D are typed as mutable.
typeof(10) == int
typeof(3.14) == double
typeof("hello") == immutable(char)[]   // array itself is mutable

Then, with new rvalue reference mechanism, literals are assigned to
mutable temporaries, and be bound to ref.

void foo(ref int n){}
foo(10);
// same as int tmp = 10; foo(tmp);

But it is less useful behavior.

I propose that if rvalue reference binding is needed, and the rvalue
is built-in literal, its type is treated as const.

void foo(ref int n){}
foo(10);
// same as const(int) tmp = 10; foo(tmp);
// tmp is const, and binding const variable to mutable ref is illegal,
then raises an error.

Finally, I don't know we should apply this rule to struct literal too.
It sounds good, but I afraid that is too restrict.

Kenji Hara

2012年4月11日13:33 Andrei Alexandrescu <andrei at erdani.com>:
> 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
>
>
> _______________________________________________
> dmd-beta mailing list
> dmd-beta at puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-beta


More information about the dmd-beta mailing list