My Reference Safety System (DIP???)

deadalnix via Digitalmars-d digitalmars-d at puremagic.com
Wed Feb 25 10:08:53 PST 2015


On Wednesday, 25 February 2015 at 01:12:15 UTC, Zach the Mystic 
wrote:
> So what are these bits? Reserve 4 bits for an unsigned integer 
> (range 0-15) I call "scopedepth". Scopedepth is easier for me 
> to think about than lifetime, of which it is simply the 
> inverse, with (0) scopedepth being infinite lifetime, 1 having 
> a lifetime at function scope, etc. Anyway, a declaration's 
> scopedepth is determined according to logic similar that found 
> in DIP69 and Mark Schutz's proposal:
>
> int r; // declaration scopedepth(0)
>
> void fun(int a /*scopedepth(0)*/) {
>   int b; // depth(1)
>   {
>     int c; // depth(2)
>     {
>       int d; // (3)
>     }
>     {
>       int e; // (3)
>     }
>   }
>   int f; // (1)
> }
>

You have element of differing lifetime at scope depth 0 so far.

> Principle 5: It's always un at safe to copy a declaration scope 
> from a higher scopedepth to a reference variable stored at 
> lower scopedepth. DIP69 tries to banish this type of thing only 
> in `scope` variables, but I'm not afraid to banish it in all 
> @safe code period:
>
> void gun() @safe {
>   T* t; // t's declaration depth: 1
>   T u;
>   {
>     T* uu = &u; // fine, this is normal
>     T tt;
>     t = &tt; // t's reference depth: 2, error, un at safe
>   }
>   // now t is corrupted
> }
>

Bingo. However, when you throw goto into the mix, weird thing 
happens. The general idea is good but need refining.

> Principle 6: Reference variables: Any data which stores a 
> reference is a "reference variable". That includes any pointer, 
> class instance, array/slice, `ref` parameter, or any struct 
> containing any of those. For the sake of simplicity, I boil 
> _all_ of these down to "T*" in this proposal. All reference 
> types are effectively the _same_ in this regard. DIP25 does not 
> indicate that it has any interest in expanding beyond `ref` 
> parameters. But all reference types are unsafe in exactly the 
> same way as `ref` is. (By the way, see footnote [1] for why I 
> think `ref` is much different from `scope`). I don't understand 
> the restriction of dIP25 to `ref` paramteres only. Part of my 
> system is to expand `return` parameter to all reference types.
>

Bingo 2!

> Principle 7: In this system, all scopes are *transitive*: any 
> reference type with double indirections inherits the scope of 
> the outermost reference. Think of it this way:
>

It is more complex than that, and this is where most proposals 
fail short (including this one and DIP69). If you want to 
disallow the assignment of a reference to something with a short 
lifetime, you can't consider scope transitive when used as a 
lvalue. You can, however, consider it transitive when used as an 
rvalue.

The more general rule is that you want to consider the largest 
possible lifetime of an lvalue, and the smallest possible one for 
an rvalue.

When going through an indirection, that will differ, unless we 
choose to tag all indirections, which is undesirable.

> Principle 8: Any time a reference is copied, the reference 
> scope inherits the *maximum* of the two scope depths:
>

That makes control flow analysis easier, so I can buy this :)

> Principle 8: We don't need to know! For all intents and 
> purposes, a reference parameter has infinite lifetime for the 
> duration of the function it is compiled in. Whenever we copy 
> any reference, we do a bitwise OR on *all* of the mystery 
> scopes. The new reference accumulates every scope it has ever 
> had access to, directly or indirectly.
>

That would allow to copy a parameter reference to a global, which 
is dead unsafe.

There is some goodness in there. Please address my comment and 
tell me if I'm wrong, but I think you didn't covered all bases.


More information about the Digitalmars-d mailing list