digitalmars.D - anonymous delegates in objects. bug?
- Ilya Zaitseff (34/34) Mar 08 2005 This code works:
- xs0 (6/53) Mar 08 2005 You made a mistake - A.this() sets the global b, while "B b=new B()"
- Ilya Zaitseff (25/32) Mar 08 2005 Oops, just a stupid typo :)
- Russ Lewis (16/43) Mar 09 2005 My guess is that the problem is that the delegate you're creating is a
- Ilya Zaitseff (3/41) Mar 10 2005 I got it. Thanks.
This code works: <code> import std.stdio; void delegate () dg; class A { this() { dg = delegate void () { foo(); }; } void foo() { writefln("foo"); } } void main() { B b = new B(); A a = new A(); dg(); // prints "foo" } </code> But this code throws AV: <code> import std.stdio; class B { void delegate () dg; } B b; class A { this() { b.dg = delegate void () { foo(); }; } void foo() { writefln("foo"); } } void main() { B b = new B(); A a = new A(); b.dg(); // AV here } </code> Whats the difference? Is it a bug or specific D behaviour?
Mar 08 2005
Ilya Zaitseff wrote:This code works: <code> import std.stdio; void delegate () dg; class A { this() { dg = delegate void () { foo(); }; } void foo() { writefln("foo"); } } void main() { B b = new B(); A a = new A(); dg(); // prints "foo" } </code> But this code throws AV: <code> import std.stdio; class B { void delegate () dg; } B b; class A { this() { b.dg = delegate void () { foo(); }; } void foo() { writefln("foo"); } } void main() { B b = new B(); A a = new A(); b.dg(); // AV here } </code> Whats the difference? Is it a bug or specific D behaviour?You made a mistake - A.this() sets the global b, while "B b=new B()" creates the local b.. When you execute b.dg(), it's not the global b, so it doesn't have the delegate set, hence AV.. In fact, I'd say that it's A.this() that produces AV, because the global b is null... xs0
Mar 08 2005
On Tue, 08 Mar 2005 18:07:00 +0100, xs0 <xs0 xs0.com> wrote:Ilya Zaitseff wrote:Oops, just a stupid typo :) Actually second code snippet is: <code> import std.stdio; class B { void delegate () dg; void run() { dg(); } } B b; class A { this() { b.dg = delegate void () { foo(); }; } void foo() { writefln("foo"); } } void main() { b = new B(); A a = new A(); b.dg(); // prints "foo" b.run(); // AV here } </code> bug, isn't it?Whats the difference? Is it a bug or specific D behaviour?You made a mistake - A.this() sets the global b, while "B b=new B()" creates the local b.. When you execute b.dg(), it's not the global b, so it doesn't have the delegate set, hence AV.. In fact, I'd say that it's A.this() that produces AV, because the global b is null... xs0
Mar 08 2005
Ilya Zaitseff wrote:<code> import std.stdio; class B { void delegate () dg; void run() { dg(); } } B b; class A { this() { b.dg = delegate void () { foo(); }; } void foo() { writefln("foo"); } } void main() { b = new B(); A a = new A(); b.dg(); // prints "foo" b.run(); // AV here } </code> bug, isn't it?My guess is that the problem is that the delegate you're creating is a stack delegate, and the stack frame is no longer valid. Remembery that the line foo(); in the delegate literal is really this.foo(); and that, since this is a stack delegate, the compiler is gettting 'this' from a function argument which was on the stack; thus, the statement really becomes stack_frame.this.foo(); where stack_frame is the pointer which is saved in the delegate. This pointer is created when the delegate literal is created, and is invalid from the moment that the stack frame (the constructor) exits. This code should work fine if you change A's constructor to this: this() { b.dg = &this.foo; }
Mar 09 2005
On Wed, 09 Mar 2005 11:09:01 -0700, Russ Lewis <spamhole-2001-07-16 deming-os.org> wrote:Ilya Zaitseff wrote:I got it. Thanks.<code> import std.stdio; class B { void delegate () dg; void run() { dg(); } } B b; class A { this() { b.dg = delegate void () { foo(); }; } void foo() { writefln("foo"); } } void main() { b = new B(); A a = new A(); b.dg(); // prints "foo" b.run(); // AV here } </code> bug, isn't it?My guess is that the problem is that the delegate you're creating is a stack delegate, and the stack frame is no longer valid. Remembery that the line foo(); in the delegate literal is really this.foo(); and that, since this is a stack delegate, the compiler is gettting 'this' from a function argument which was on the stack; thus, the statement really becomes stack_frame.this.foo(); where stack_frame is the pointer which is saved in the delegate. This pointer is created when the delegate literal is created, and is invalid from the moment that the stack frame (the constructor) exits. This code should work fine if you change A's constructor to this: this() { b.dg = &this.foo; }
Mar 10 2005