Rvalue references - The resolution

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sat May 4 17:28:55 PDT 2013


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]); }

> 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.

> 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.

> 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.

> 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;" and "return a[13];".


Andrei


More information about the Digitalmars-d mailing list