Safe Regions with Deterministic Destruction

ag0aep6g anonymous at example.com
Tue Oct 27 15:33:08 UTC 2020


On 27.10.20 08:07, Ola Fosheim Grøstad wrote:
> But technically the t.root pointer address is a value, so apparently 
> scope does not apply only to t, but also to the member root?

I'm not sure what you mean by "is a value". `t.root` is a class 
reference, which (to `scope`) is a pointer with a fancy name. It being 
an indirection is what makes it interesting. `scope` doesn't do anything 
for non-indirections.

But yes, `scope` applies to `t.root`, because it's the first level of 
indirection in `t`. If it was `t.x.y.z.root`, with `x`, `y`, and `z` 
being more structs, `scope` would still apply to `root`. But if `x`, 
`y`, or `z` were some kind of indirection, `scope` would apply to that 
and not to `root`.

`scope` doesn't work on types. It works on indirections. `scope` sees 
through types until it finds an indirection. And then it stops. If you 
have two or more levels of indirections, `scope` still only affects the 
first.

An example in code:

----
struct A
{
     int* pa;
     B b;
}
struct B
{
     int* pb;
     C* c;
}
struct C
{
     int* pc;
     int x;
}
int* f(scope A a) @safe
{
     return a.pa; /* error; can't return a `scope` pointer */
     return a.b.pb; /* error; still covered by `scope` */
     return a.b.c.pc; /* ok; `scope` is not transitive */
}
----

If you replace `scope` with `const`, all three lines fail, because 
`const` is transitive.

(Note: `ref` is handled differently from other forms of indirection.)

> So if Node was a linked list, then t.root is limited by escape analysis, 
> but not t.root.next?

Exactly.


More information about the Digitalmars-d mailing list