Steven Schveighoffer Wrote:
> remember, scope is a storage class, not a type modifier. "scopeness" is
> only a hint to the compiler of where to store it originally, the hint is
> not passed on to other variables which point to the same data. I'm
> surprised it's actually an error to try and return a scope variable.
>
> One way to get scope to work as you desire is to make it a type modifier
> and define rules about assignment, but I'm not sure that's a good answer.
> Another way is to perform escape analysis, but Walter has expressed that
> he doesn't want to do that. It would require an intermediate interface
> language for imports where annotations could be added by the compiler.
It seems that scopeness as-is is not a "hint to the compiler of where to store
it originally" because scope reference accepts object which is not allocated at
there.
Here is a example:
class C
{
int i = 1;
~this() { writeln("~C"); }
void foo() {}
}
int* f(C arg) {
scope c = arg;
return &(c.i);
}
void main()
{
auto c = new C;
auto p = f(c); // destructor is called after f()
writeln(*p); // success, at first grance
c.foo; // runtime error: access violation
}
The instance have been collected, hence escaped pointer probably points a
garbage.
The 'scope' is misleading rather than a hint in this case, since resource had
been acquired far away from the 'scope'.
Current behaviors of 'scope' are:
1. Prohibit to return the scope references (as you said, it is a storage class
and not transitive). (compile time)
2. Calling destructor for the referenced instance when the reference goes out
of scope. (runtime)
I think RAII has similarity to const/immutable, which is fully cared in D2:
* It is safe to reference values/objects from multi-thread, etc. if the
referenced object will not change.
* It is safe to destruct a object when reference goes out of scope if the
object is referenced only from the scope.
Consequently, the best answer is presumably make it a transitive type modifier.
At least adding rules about assignment, right-hand value of 'scope' reference
must be just allocated by new operator.
It is too dangerous to allow referencing any object, especially parameter of
the function.
I agree that escape analysis is bad solution because it makes compiler
implementation too hard.