[dmd-beta] rvalue references

Andrei Alexandrescu andrei at erdani.com
Sat Apr 14 20:42:14 PDT 2012


This part of the proposal is sound but I fear it could cause confusion.
It is a special rule, and special rules may be surprising.

Also I don't know when people have bugs because of it. I mean when is
the last time anyone called swap(10, 20)?

Let me see the second part.


Andrei

On 4/13/12 12:58 AM, kenji hara wrote:
> 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
> _______________________________________________
> 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