Const ref and rvalues again...
Jonathan M Davis
jmdavisProg at gmx.com
Fri Nov 9 11:39:06 PST 2012
On Friday, November 09, 2012 15:55:12 Manu wrote:
> Does that actually make sense? Surely a function that receives a scope
> argument can return that argument, since it's only passing it back to the
> same function that already owns it... it knows it can trust that function,
> since it was received from that function.
It can't. That would mean that the reference escaped. That would be
particularly deadly for delegates. Think about what happens if the scoped
delegate is put into a struct which is returned.
struct Result
{
delegate........ del;
...........
}
Result foo(scope delegate....... bar)
{
..........
return Result(bar);
}
auto baz()
{
Result r;
{
int n = 5;
r = foo((){writeln(n);});
}
r.del();
}
baz has no idea where the delegate in r came from. It has no idea that it
wasn't allocated as a closure. So, it's not going to allocate one, which means
that the delegate refers to a part of the stack which won't exist anymore when
the delegate actually gets called. If scope wasn't used, that wouldn't have
been a problem, because a closure would have been allocated as soon as the
delegate had been passed to foo, but because scope was used, it knows that the
delegate won't escape, so it doesn't allocate the closure (since it's not
necessary). But that only works because scope prevents escaping - including by
the return value. So, the above code _must_ be invalid.
>> Any struct holding any reference types would be
> > in the same boat, as would any class or AA.
>
> I don't follow the problem with reference args. surely they can be
> evaluated just fine? Just that nothing can escape the function...
It's the fact that they can't escape the function which is the problem. If
scope is working correctly, than any and all reference types which are passed
to the function via a scope parameter (be it directly or within another
object) cannot escape the function in any way shape or form. So, you can't
assign any of them to any static or module-level variables (not generally a
big deal) and you can't use any of them in the return value (often a big
deal). Sometimes, that's exactly what you want, but in the general case, you
don't want to prevent anything you pass into a function from being returned
from it, so scope quickly becames overly restrictive.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list