On 10 November 2012 21:07, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
On Saturday, November 10, 2012 13:21:42 Manu wrote:Hmmmm. scope on value types is pointless, because there are no references to
> 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.
escape, but if you pass by ref, then it does become possible for a pointer to
the argument to escape,
but I don't know that that's actually actually covered
by scope. The description for scope in docs is that "references in the pa
rameter cannot be escaped (e.g. assigned to a global variable)." And
taking the address of a local variable (which is the only way that any sort of
reference to the data could escape) is never @safe anyway.
If you passed in a
pointer, and scope were fully working, then you'd be protected against the
pointer escaping, but passing by ref isn't really the same thing. I'd have
thought that taking the address of a variable passed by ref would fall into
pretty much the same camp as taking the address of any other local variable,
which is completely unsafe to escape to the point that I'm not sure that
there's any point in protecting against it. It's just completely stupid to do
anyway and is definitely @system. Outside of taking the address of a ref
parameter, taking the address of a local variable and escpaing it is _always_
going to result in garbage, and ref parameters aren't really references in the
normal sense, so I don't know.
You bring up a good point, but I don't know if it's applicable. Certainly,
without the ref there (like is the case with the Vector that you're passing
in), scope would never do anything, because it doesn't even theoretically have
anything to do. It's purely a value type that's not even being passed by ref.
In general though, putting scope on struct parameters would cause a lot of
problems, because of arrays that they might hold and whatnot. Slices wouldn't
be able to escape (and so copies of the struct wouldn't be able escape without
deep copying, let alone the array itself).
So, while scope may be very useful
in some such cases (assuming that it worked), it's not necessarily something
that you'd want as a matter of course.
Part of it probably depends on your
programming style though. If you have a lot of functions that take arguments
and don't return anything that was in them ever, then scope is less of a big
deal, but that's the sort of thing that happens a _lot_ in my experience, so
scope would very quickly become extremely annoying.
And actually, to make matters worse, I'm not sure that scope on delegates is
working correctly. I thought that it was, but this code compiles:
import std.stdio;
void delegate() global;
void foo(scope void delegate() del)
{
global = del;
}
void main()
{
{
char[5] bar = "hello";
foo((){writeln(bar);});
}
char[7] baz = "goodbye";
global();
}
It also prints out "hello", and if a closure had not been allocated, I would
have at least half-expected it to print out "goodb", because I'd have thought
that baz would have been taking up the same memory that bar had been. So, it
looks like scope may be completely and utterly broken at this point. I don't
know.
- Jonathan M Davis