Const ref and rvalues again...

Manu turkeyman at gmail.com
Sat Nov 10 03:21:42 PST 2012


On 9 November 2012 21:39, Jonathan M Davis <jmdavisProg at gmx.com> wrote:

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

Okay, makes sense.

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

I'm still not buying this. Here's a common struct I will pass by ref
(perhaps the most common struct in my industry):

struct Vector { float, x,y,z,w; }
struct Matrix { Vector xRow, yRow, zRow, wRow; }

Vector mul( scope const ref Matrix m, scope const Vector v)
{
  Vector v;
  // perform a matrix multiply against the vector...
  // this work uses every single field of the inputs given, but the result
it produces has to references to the sources.
  // everything is operated on and copied to the output struct, which is
returned.
  return result;
}

Why should this be a problem?
The majority of my work-horse structs apply to this pattern. This is what I
imagine 'scope' to be for...
The main advantage I expect is that I can have confidence that passing
rvalues (temporaries) is safe, and that external code won't take references
to memory that I may not own/control. Is that not the point?

Surely the problem that scope should be protecting against is a pointer to
any part of the argument escaping. *Copies* of values contained in the
argument/s are fine.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20121110/4d26aa59/attachment.html>


More information about the Digitalmars-d mailing list