Bug 6052 – [CTFE] Structs elements in an array are treated like reference type
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Mac OS X
Creation time
2011-05-24T09:06:00Z
Last change time
2011-06-01T22:49:08Z
Keywords
wrong-code
Assigned to
nobody
Creator
kennytm
Comments
Comment #0 by kennytm — 2011-05-24T09:06:57Z
Test case:
--------------------------------------------------
struct Bug6052 {
int a;
}
bool bug6052() {
Bug6052[2] arr;
for (int i = 0; i < 2; ++ i) {
Bug6052 el = {i};
Bug6052 ek = el;
arr[i] = el;
el.a = i + 2;
assert(ek.a == i); // ok
assert(arr[i].a == i); // fail
}
assert(arr[1].a == 1); // ok
assert(arr[0].a == 0); // fail
return true;
}
static assert(bug6052());
--------------------------------------------------
x.d(16): Error: assert(arr[cast(uint)i].a == i) failed
x.d(23): Error: cannot evaluate bug6052() at compile time
x.d(23): Error: static assert (bug6052()) is not evaluatable at compile time
--------------------------------------------------
Setting a struct value on a array should perform a bit-copy, so modifying 'el' should not affect 'arr[i]', but currently CTFE does it wrongly.
Comment #1 by kennytm — 2011-05-24T09:10:47Z
Note: the last 2 asserts refer to the case when the line 'el.a = i + 2;' is commented out.
The bug still exists if the the struct has a constructor and we're appending to a dynamic array....
---------------------------------------------
struct Bug6052c {
int x;
this(int a) { x = a; }
}
static assert({
Bug6052c[] pieces = [];
for (int c = 0; c < 2; ++ c)
pieces ~= Bug6052c(c);
assert(pieces[1].x == 1); // ok
assert(pieces[0].x == 0); // asserts
return true;
}());
---------------------------------------------
x.d(10): Error: assert(pieces[0u].x == 0) failed
<snipped>
---------------------------------------------
or filling the uninitialized portion of a dynamic array....
---------------------------------------------
static assert({
int[1][] pieces = [];
pieces.length = 2;
for (int c = 0; c < 2; ++ c)
pieces[c][0] = c;
assert(pieces[1][0] == 1); // ok
assert(pieces[0][0] == 0); // asserts
return true;
}());
---------------------------------------------
x.d(7): Error: assert(pieces[0u][0u] == 0) failed
<snipped>
---------------------------------------------