Bug 20285 – Struct destructor called multiple times in dynamic arrays

Status
NEW
Severity
normal
Priority
P3
Component
druntime
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2019-10-08T19:46:24Z
Last change time
2024-12-07T13:39:43Z
Assigned to
No Owner
Creator
Graham St Jack
Moved to GitHub: dmd#17391 →

Comments

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
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17391 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB