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 ***