Is this a bug or feature?
Kirk McDonald
kirklin.mcdonald at gmail.com
Tue Jan 16 02:30:40 PST 2007
Li Jie wrote:
> Code:
>
> # import std.gc;
> #
> # class Foo{
> # private:
> # int value = 3;
> #
> # public:
> # ~this(){
> # writefln("call destructor");
> # }
> #
> # void delegate() foo(){
> # return delegate void(){
> # writefln(value);
> # };
> # }
> # }
> #
> # void main(){
> # void delegate() dg = (new Foo).foo;
> # std.gc.fullCollect();
> # dg();
> # }
>
> I expect it output "3", but the output is a big number, not "3".
>
> If comment std.gc.fullCollect(), it output "3", and it is right.
>
> I think a closure must save all contexts, isn't it?
D does not have true closures. If the stack frame of the enclosing
function is invalidated, then all bets are off.
In Foo.foo above, the 'value' variable is a member of the 'this'
reference. When Foo.foo returns, that delegate literal's context pointer
is invalidated, and (therefore) so is the 'this' reference.
If you want a delegate with a more persistent context, you must use a
delegate to a member function, as in:
class Foo {
int value = 3;
~this() { writefln("dtor"); }
void foo() {
writefln(value);
}
}
void main() {
// Note the '&'
void delegate() dg = &(new Foo).foo;
std.gc.fullCollect();
dg();
}
--
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org
More information about the Digitalmars-d-learn
mailing list