Bug 8740 – Temporary structs inside of array literals are destroyed and not copied in initialization of array
Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-09-30T07:32:00Z
Last change time
2013-05-09T02:12:44Z
Assigned to
nobody
Creator
dmitry.olsh
Comments
Comment #0 by dmitry.olsh — 2012-09-30T07:32:49Z
See subject. Which is wrong and is unlike e.g. array append.
Synposis:
version (msg) import std.stdio;
void main()
{
struct Int
{
int* payload;
this(int k)
{
payload = new int;
*payload = k;
version(msg) writeln("created: ", k);
}
this(this)
{
int* np = new int;
*np = *payload;
payload = np;
version(msg) writeln("dupped: ", *payload);
}
~this()
{
version(msg) writeln("destroyed: ", *payload);
*payload = 0; //'destroy' it
}
@property int getPayload(){ return *payload; }
alias getPayload this;
}
//this destroys but not copies
Int[] arr = [Int(1), Int(4), Int(5)];
assert(arr[0] == 0); //passes while shouldn't (expected == 1)
assert(arr[1] == 0); //ditto with 4
assert(arr[2] == 0); //ditto with 5
//this one does create/copy/destroy
Int[] arr2;
arr2 ~= [Int(1), Int(4), Int(5)]; // this copies things over unlike first case
assert(arr2[0] == 1);
assert(arr2[1] == 4);
assert(arr2[2] == 5);
}
Clearly Int[] arr = [...]; doesn't copy each element in turn, as is evident if version=msg is specified:
created: 1
created: 4
created: 5
destroyed: 5
destroyed: 4
destroyed: 1
created: 1
created: 4
created: 5
dupped: 1
dupped: 4
dupped: 5
destroyed: 5
destroyed: 4
destroyed: 1
I argue that ideally the first and the 2nd version should just move temporaries and never destroy them in the first place.
But minimally compiler should copy(dup) them in both cases if it can't figure out how to move.
Compiler: DMD 2.061 as of git commit caf289137881ec290166afa72bc787bfbd6bd970
Comment #1 by k.hara.pg — 2013-05-09T02:12:44Z
In 2.063a, the OP code prints following output by fixing issue 9386 (need to mask assertions).
created: 1
created: 4
created: 5
created: 1
created: 4
created: 5
dupped: 1
dupped: 4
dupped: 5
In the first place, array literal is just created in heap, so there is no copy.
In the second place, array literal is created, and concatenation copies the elements to the new array.
I think this is expected behavior, so mark this "RESOLVED".
*** This issue has been marked as a duplicate of issue 9386 ***