[Issue 17897] Postblit is not called for temporary structures in the function parameters

d-bugmail at puremagic.com d-bugmail at puremagic.com
Fri Oct 13 13:51:48 UTC 2017


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

--- Comment #4 from Simen Kjaeraas <simen.kjaras at gmail.com> ---
(In reply to Steven Schveighoffer from comment #1)
> Postblit is not called for moves.

You're misreading the bug report (not surprising, as it was marked
incorrectly). Expanded example:

import std.stdio;

struct Foo {
    this(int) {}
    ~this() {}
}

struct Baz {}

struct Bar(T) {
    this(T a) {
        writefln("Bar.this(T): %X", &this);
    }
    this(T a, T b) {
        writefln("Bar.this(T, T): %X", &this);
    }
    ~this() {
        writefln("Bar.~this(): %X", &this);
    }
}

void fun(T)(Bar!T n) {
    writefln("fun: %X", &n);
}

unittest { // 1
    // Basically what Jack posted:
    int n;
    writefln("\nunittest 1: %X", &n);
    fun(Bar!Foo(Foo(0), Foo(0)));
}

unittest { // 2
    // Single Foo in Bar's constructor:
    int n;
    writefln("\nunittest 2: %X", &n);
    fun(Bar!Foo(Foo(0)));
}

unittest { // 3
    // Saving Foo(0) to a temporary:
    int n;
    writefln("\nunittest 3: %X", &n);
    auto foo = Foo(0);
    fun(Bar!Foo(foo, foo));
}

unittest { // 4
    // using a type without constructor and destructor:
    int n;
    writefln("\nunittest 4: %X", &n);
    fun(Bar!Baz(Baz(), Baz()));
}

Which gives this output:

unittest 1: 19FDAC
Bar.this(T, T): 19FDB3
fun: 19FD80
Bar.~this(): 19FD80
Bar.~this(): 19FDB3

unittest 2: 19FDB4
Bar.this(T): 19FDB8
fun: 19FD8C
Bar.~this(): 19FD8C

unittest 3: 19FDA8
Bar.this(T, T): 19FDAD
fun: 19FD7C
Bar.~this(): 19FD7C

unittest 4: 19FDB8
Bar.this(T, T): 19FDBC
fun: 19FD94
Bar.~this(): 19FD94

As we can see for unittest1, the destructor is called twice - once for the
temporary in the unittest block, and once when  we exit fun().

This is caused by some interaction with Foo's constructor and destructor, as
evinced by the fact that commenting out either fixes the problem (see unittest
4). Other things that fixes it include changing Bar's constructor to take a
single Foo instead of two (as seen in unittest 2), and saving Foo(0) to a
temporary before passing it to Bar() (as seen in unittest 3).

--


More information about the Digitalmars-d-bugs mailing list