The next iteration of scope

Zach the Mystic via Digitalmars-d digitalmars-d at puremagic.com
Mon Mar 16 08:25:43 PDT 2015


On Monday, 16 March 2015 at 13:55:43 UTC, Marc Sch├╝tz wrote:
>> Also, what exactly does the `scope` on T payload get you? Is 
>> it just a more specific version of `return` on the this 
>> parameter, i.e. `return this.payload`? Why would you need that 
>> specificity? What is the dangerous operation it is intended to 
>> prevent?
>
> Nick already answered that. I'll expand on his explanation:
>
> Let's take the RC struct as an example. Instances of RC can 
> appear with and without scope. Because structs members inherit 
> the scope-ness from the struct, `payload` could therefore be an 
> unscoped pointer. It could therefore be escaped 
> unintentionally. By adding `scope` to its declaration, we force 
> it to be scoped to the structs lifetime, no matter how it's 
> accessed.

If an RC'd struct is heap-allocated, but one of its members 
points to the stack, how is it ever safe to escape it? Why 
shouldn't the heap variable be treated as scoped too, inheriting 
the most restricted scope of any of its members? To me, the 
question is not how you can know that a member is scoped, so much 
as how you could know that it *isn't* scoped, i.e. that a 
sub-pointer was global while the parent was local. I think it 
would require a very complicated type system:

struct S {
   T* p;
}

// note the elaborate new return signature
T* fun(return!(S.p) S x) {
   return x.p;
}

T* run() {
   S s;
   s.p = new T; // s local, s.p global
   return fun(s);
}

The above is technically safe, but the question is whether it's 
too complicated for the benefit. In the absence of such a 
complicated system, the safe default is to assume a struct is 
always as scoped as its most scoped member (i.e. transitive 
scoping). Your idea of `scope` members would only be valid in the 
absence of this safe default. But even then it would be of 
limited usefulness, because it would prevent all uses of global 
references in those members, even if the parent was global. For 
me, it comes down to that you can't know if anything is global or 
local until you define an instance of it, which you can't do in 
the struct definition.


More information about the Digitalmars-d mailing list