DIP 1014

Stanislav Blinov stanislav.blinov at gmail.com
Wed Oct 3 15:05:52 UTC 2018


On Wednesday, 3 October 2018 at 14:07:58 UTC, Shachar Shemesh 
wrote:

> If you read the DIP, you will notice that the *address* in 
> which the old instance resides is quite important...

Allow me to further illustrate with something that can be written 
in D today:

import std.stdio;

struct Tracker {
     static int globalCounter;
     int localCounter;
     int* counter;

     this (bool local) {
         if (local) counter = &localCounter;
         else counter = &globalCounter;
     }

     // this should be this(Tracker rhs)
     void opAssign(Tracker rhs) {
         // note: taking address of local parameter
         // note: LDC will already 'optimize' the move which in 
the absence
         // of any move hooks will mess up the address; try with 
DMD
         printf("Address of temporary is '%x', counter points to 
'%x'\n", &rhs, rhs.counter);
         auto d = cast(void*) rhs.counter - cast(void*) &rhs;
         printf("... which is '%ld' bytes from the address of 
temporary.\n", d);
         localCounter = rhs.localCounter;
         counter = rhs.counter;
         if (counter is &rhs.localCounter)
             counter = &localCounter;
     }
}

auto createCounter(bool local = true) {
     Tracker result = Tracker(local);
     return result;
}

auto createCounterNoNRV(bool local = true) {
     return Tracker(local);
}

void main() {

     Tracker stale1, stale2;

     stale1 = createCounter();
     stale2 = createCounter(false);

     Tracker stale3, stale4;

     stale3 = createCounterNoNRV();
     stale4 = createCounterNoNRV(false);
}


If you run the above with DMD, you'll see what I mean about 
obviating the address. If we get this(typeof(this)) (that is 
*always* called on move) into the language, the behavior would be 
set in stone regardless of compiler.


More information about the Digitalmars-d mailing list