DIP1000: Scoped Pointers

Sönke Ludwig via Digitalmars-d-announce digitalmars-d-announce at puremagic.com
Thu Aug 11 06:38:30 PDT 2016


This looks like the best proposal so far. Many useful ideas, and at the 
first glance it looks like a big step forward. I also really like how 
the useful stack allocation behavior for closures and new'ed values is 
kept alive.

What would be nice to add is a behavior specification for 'scope' member 
variables (lifetime considered equal or slightly shorter than parent 
object lifetime). For example the `RefCountedSlice.payload` and `count` 
fields could be annotated with 'scope' to let the compiler actually 
guarantee that they won't be accessible in a way that conflicts with 
their lifetime (i.e. the 'scope' return of 'opIndex' would actually be 
enforced).

That will just leave one hole in conjunction with the @trusted 
destructor, which is (presumably) not easy to fix without much larger 
changes to the type system, as well as to how container types are built. 
It is still vulnerable to artificial shortening of the elements' 
lifetime, e.g. by using opAssign() or destroy():

@safe {
     RefCountedSlice!int s = ...;
     scope int* el;
     el = &s[0];
     s = RefCountedSlice.init;
     *el = 12; // oops
}

A similar issue affects the library implementation of isolated memory 
that I did a while ago:

@safe {
     class C { int* x; }

     // c is guaranteed to be only reachable through this variable
     Isolated!C c = makeIsolated!C();

     // c.x is a @property that returns a specially wrapped reference to
     // the actual C.x field - with this DIP this is similar to a 'scope'
     // return, but acts transitively
     Scoped!(int*) x = c.x;

     // one of the benefits of Isolated!T is that it allows @safe
     // conversion to immutable:
     immutable(C) ci = c.freeze();
     // c gets cleared by freeze() to disallow any further modifications

     // but, oops, x is still there and can be used to modify the now
     // immutable contents of ci.x
     *x = 12;
}

Disallowing the assignment of scope return references to local scope 
references (either by default, or using some form of additional 
inference/annotation) would solve this particular issue, but not the 
issue in general (the assignment/destruction could for example happen in 
a nested function call).



More information about the Digitalmars-d-announce mailing list