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