Comment #0 by graham.stjack — 2019-10-08T19:46:24Z
With dmd 2.088, this code:
import std.stdio;
struct Foo {
int value;
@disable this(this);
~this() { writefln("Destroying foo %s", value); }
}
void main() {
Foo[] array;
array.length = 1;
array[0] = Foo(0);
array.length = 2;
array[1] = Foo(1);
}
produces this output:
Destroying foo 0
Destroying foo 0
Destroying foo 0
Destroying foo 1
Destroying foo 0
when what I want is:
Destroying foo 0
Destroying foo 1
I assume that despite Foo being uncopyable, it is being copied by the dynamic array implementation rather than being moved.
Comment #1 by kinke — 2019-10-08T21:41:49Z
This shows better what's going on:
void main() {
Foo[] array;
array.length = 1;
array[0] = Foo(1);
printf("1st pointer: %p\n", array.ptr);
array.length = 2;
array[1] = Foo(2);
printf("2nd pointer: %p\n", array.ptr);
}
=>
Destroying foo 0
1st pointer: 0x7f9cf69b3000
Destroying foo 0
2nd pointer: 0x7f9cf69b4000
Destroying foo 1
Destroying foo 2
Destroying foo 1
Increasing the length default-constructs instances at the end, which are destructed when assigning the literals later. These are the first 2 dtor calls.
As a reallocation takes places, the two GC arrays are destructed on program termination, these are the other 3 dtor calls. Here, the 1st 1-element-array should probably not be destructed, as it's been moved from (and it hasn't been reset to T.init either).
Comment #2 by maxsamukha — 2019-10-09T06:16:08Z
Bugs like this should not be marked normal. They are critical at least.
Comment #3 by robert.schadek — 2024-12-07T13:39:43Z