Bug 6768 – Problem with init of struct members in presence of templated opAssign

Status
RESOLVED
Resolution
DUPLICATE
Severity
critical
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
Windows
Creation time
2011-10-04T19:14:00Z
Last change time
2012-11-12T01:25:48Z
Keywords
wrong-code
Assigned to
nobody
Creator
andrej.mitrovich
Blocks
2573

Comments

Comment #0 by andrej.mitrovich — 2011-10-04T19:14:34Z
module test; import std.traits; import std.stdio; struct Point { int x, y; void delegate() dg; // void opAssign(void delegate() rhs) // ok, x and y initialized // { // dg = rhs; // } void opAssign(T)(T rhs) if (isDelegate!T) // x and y left uninitialized { dg = rhs; } void test() { dg(); } } class Foo { this() { point = { writefln("Point: %s", point); }; // assign delegate } Point point; } void main() { auto foo = new Foo; foo.point.dg(); // x and y are initialized foo.point.test(); // but here x and y are not initialized (??) foo.point.dg(); // again, not initialized (??) } I don't understand how calling dg() directly or indirectly via test() prints different results for x and y. If I use the non-templated version of opAssign then both calls are fine, with x and y being zero-inited.
Comment #1 by andrej.mitrovich — 2012-01-04T06:49:54Z
In 2.057 all calls to the `dg` delegate print garbage values if the templated opAssign was used: Point: Point(4202703, 4931824, void delegate()) Point: Point(1244728, 4202612, void delegate()) Point: Point(4202726, 4931824, void delegate())
Comment #2 by smjg — 2012-02-12T13:05:02Z
(In reply to comment #1) > In 2.057 all calls to the `dg` delegate print garbage values if the templated > opAssign was used: Not for me (2.057 Win32): ----- C:\Users\Stewart\Documents\Programming\D\Tests\bugs>bz6768 Point: Point(0, 0, void delegate()) Point: Point(1244752, 4202612, void delegate()) Point: Point(1244752, 4202612, void delegate()) ----- It's especially puzzling because after construction of foo, our code hasn't changed either foo or foo.point, but something behind the scenes has caused it to change.
Comment #3 by verylonglogin.reg — 2012-11-12T01:25:48Z
The issue isn't with `opAssign`. It is because closure isn't detected: --- import std.stdio; void setDel()(Foo foo, void delegate() del) { foo.del = del; } class Foo { void delegate() del; void f() { writefln("%X, %X (instance and ref addresses)", cast(void*) this, &this); void g() { writefln("%X, %X (instance and ref addresses from g)", cast(void*) this, &this); } setDel(this, &g); writefln("%X (del.ptr)", del.ptr); } void callDel() { writefln("+callDel"); del(); writefln("-callDel"); } } void main() { auto foo = new Foo(); foo.f(); foo.del(); foo.callDel(); foo.del(); } --- Output: --- A01E70, 12FE58 (instance and ref addresses) 12FE58 (del.ptr) 12FE58, 12FE58 (instance and ref addresses from g) +callDel A01E70, 12FE58 (instance and ref addresses from g) -callDel 12FE58, 12FE58 (instance and ref addresses from g) --- Created a new issue with corrected title and description. *** This issue has been marked as a duplicate of issue 8999 ***