[Issue 17448] Move semantics cause memory corruption and cryptic bugs

d-bugmail at puremagic.com d-bugmail at puremagic.com
Mon May 30 16:57:35 UTC 2022


https://issues.dlang.org/show_bug.cgi?id=17448

--- Comment #48 from Tomer Filiba (weka) <tomer at weka.io> ---
Steven, can we agree that the following snippet is NOT okay? 
Regardless of @safe, let's leave it out of question.

As a bonus, it this does not involve any library code/special moves/self
references. And I used the latest dmd from run.dlang.io.

```d

__gshared S* lastS = null;

struct S {
    int x;
    this(int x) {
        this.x = x;
        lastS = &this;
    }
}

S f(int x) {
    return S(x);
}

void main() {
    S s1 = S(6);
    writeln("&s1=", &s1, " lastS=", lastS, " diff=", cast(void*)&s1 -
cast(void*)lastS);
    // &s1=7FFD2262F468 lastS=7FFD2262F468 diff=0

    S s2 = f(5);
    writeln("&s2=", &s2, " lastS=", lastS, " diff=", cast(void*)&s2 -
cast(void*)lastS);
        // &s2=7FFD2262F46C lastS=7FFD2262F3F8 diff=116
}
```

* The first example, s1, is created using the ctor directly, which means
there's no move and `&s1 == lastS`.
* The second example, s2, return a struct via a function. Here we get an
implicit move and lastS points to garbage, 116 bytes away from s2. 
* This means that if I use lastS, I'm either reading garbage from it, or
corrupting my stack (i.e., assume I'm calling another function afterwards,
which does `lastS.x = 17`)

--


More information about the Digitalmars-d-bugs mailing list