Rvalue references - The resolution

Walter Bright newshound2 at digitalmars.com
Sat May 4 19:25:18 PDT 2013


On 5/4/2013 5:28 PM, Andrei Alexandrescu wrote:
> Couple amendments:
>
> On 5/4/13 2:33 PM, Walter Bright wrote:
>> Case B:
>> ref T foob(ref U u) { return u.t; } // note that T is derivable from U
>> ref U bar() { T t; return foob(t); }
>
> That's not derivable, it's embedded: type U transitively has a member of type T.
>
> Same case applies to statically-sized arrays:
>
> ref T foob(ref T[42] u) { return u[13]; }
> ref T[42] bar() { T[42] t; return foob(t); }
>
> Here the notion that a statically-sized arrays behaves much like a struct is
> applicable. This case probably deserves notice too:
>
> ref T fooa(ref T t) { return t; }
> ref T bar() { T[42] t; return fooa(t[13]); }

Yes.

>> 1. Always involves a return statement.
>
> Except if pointers are used, which leaves the question of what we do when people
> take the address of refs returned by functions.

Ref is a restricted form of pointer, the whole point of them is so we can do 
more reasoning about them. If we throw into the mix allowing converting them to 
pointers in safe code, everything falls apart.

>> 2. The return type must always be the type of the stack variable or a
>> type type derived from a stack variable's type via safe casting or
>> subtyping.
>
> That's not subtyping, it's transitive member access. Here transitive goes
> through members but not through indirections. Not sure how to call that to not
> make it confusing.

I know what you mean. I don't know what word to use, either.


>> 3. Returning rvalues is the same issue, as rvalues are always turned
>> into local stack temporaries.
>
> The complicating factor here is that lvalues have well-understood lifetimes
> whereas rvalues are more subtle and opened to subtleties and interpretations. I
> think right now D destroys temporaries too early.

Considering that we only have to deal with return statement expressions here, 
where the lifetime of those temporaries would be restricted to those expressions 
regardless, that shouldn't be an issue.


>> 4. Whether a function returns a ref derived from a parameter or not is
>> not reflected in the function signature.
>
> Yes! That's why any static solution is either conservative or complicates the
> language.
>
>> 5. Always involves passing a local by ref to a function that returns by
>> ref, and that function gets called in a return statement.
>
> There's also the case of e.g. "return *p;"

Again, allowing ref <=> pointer conversions makes it impractical to reason about 
refs.

> and "return a[13];".

If 'a' is a local array allocated on the stack, this is trivially disallowed, 
just like:

     S s;
     return s.t;

would be.



More information about the Digitalmars-d mailing list