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