Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
March 08, 2005 anonymous delegates in objects. bug? | ||||
---|---|---|---|---|
| ||||
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? |
March 08, 2005 Re: anonymous delegates in objects. bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ilya Zaitseff | 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
|
March 08, 2005 Re: anonymous delegates in objects. bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to xs0 | On Tue, 08 Mar 2005 18:07:00 +0100, xs0 <xs0@xs0.com> wrote:
> Ilya Zaitseff wrote:
>> 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
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?
|
March 09, 2005 Re: anonymous delegates in objects. bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ilya Zaitseff | 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; }
|
March 10, 2005 Re: anonymous delegates in objects. bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | On Wed, 09 Mar 2005 11:09:01 -0700, Russ Lewis <spamhole-2001-07-16@deming-os.org> wrote: > 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; } I got it. Thanks. |
Copyright © 1999-2021 by the D Language Foundation