The following code doesn't work with @safe -dip1000:

    int* p;
    int i;
    p = &i;

i has a shorter lifetime than p, the compiler complains.

But this code does:

    int i;
    int* p;
    p = &i;

In both cases, p can't point to i before i exists, and p ceases to exist 
when i ceases to exist.

I believe this is because the first option would let me write:

    struct Foo
    {
      bool exists = true;
      ~this() { exists = false; }
      void doStuff() { assert(exists); }
    }

    Foo* p;
    scope(exit) (*p).doStuff;
    Foo f;
    scope(exit) destroy(f);
    p = &f;

And this will run into the assert when -dip1000 should ensure it can't.

The compiler does this even in the absence of scope guards and destructors 
because simple, obvious rules will be easier to understand and implement 
than nuanced ones, even if it makes you reorder declarations sometimes.

Is this right?

Reply via email to