Struct delegate access corruption

tsbockman thomas.bockman at gmail.com
Thu Feb 18 23:02:16 UTC 2021


On Thursday, 18 February 2021 at 08:29:48 UTC, kinke wrote:
> Nope, Paul is right, the copy ctors don't solve anything in 
> this regard. Simplest example I could come up with: 
> https://run.dlang.io/is/TgxyU3

I found that example very confusing, as it does not contain an 
explicit copy constructor, violate memory safety, or output 
incorrect results.

However, I experimented with it and I think figured out what 
you're getting at? Copy constructors (and postblits) may not be 
called for moves. I guess that makes sense...

///////////////////////////
import std.stdio : write, writeln;

struct S {
     private const(S*) self, old = null;

     this(bool refSelf) inout pure @trusted {
         if(refSelf)
         	self = &this;
     }
     @disable this(this) inout pure @safe;
     this(scope ref inout(typeof(this)) that) inout pure @trusted {
         self = &this;
         old = &that;
     }

     void print() const @safe {
         write(&this);
         if(old is null)
             write(" (never copied)");
         else
             write(" (last copied from ", old, " to ", self, ")");
         writeln(" in sync: ", self is &this);
     }
}

S makeS() @safe {
     S s = true;
     s.print();
     return s; // NRVO
}

void takeS(S s) @safe {
     s.print();
}

void main() @safe {
     S s = true;
     s.print();

     takeS(s);
     takeS(makeS());
}
///////////////////////////

This works on LDC, but fails on DMD with output:

7FFF765249A0 (never copied) in sync: true
7FFF765249C0 (last copied from 7FFF765249A0 to 7FFF765249D0) in 
sync: false
7FFF76524A00 (never copied) in sync: true
7FFF765249F0 (never copied) in sync: false

(It's weird that DMD runs the copy constructor with a destination 
address that isn't even the real destination.)

Anyway, thanks for helping me understand, everyone.


More information about the Digitalmars-d-learn mailing list