Out of curiosity, I wrote this:
import std.stdio;
class A
{
B b;
~this()
{
delete b;
writefln("a dtor: ",cast(void*)b);
}
}
class B
{
A a;
~this()
{
delete a;
writefln("b dtor: ",cast(void*)a);
}
}
void main()
{
A a=new A;
B b=new B;
a.b=b;
b.a=a;
delete a;
fflush(stdout);
}
I expected it to get caught in an infinite loop between the two dtors, but
surprisingly, all that is printed is
a dtor: 0
b dtor: 0
But then, the program hangs in gc_term().
What is happening here? Why don't the objects get caught in an infinite
loop between their dtors? And if they're no longer pointing to one another
after they are dtor'ed (but most likely not GCed), why does gc_term() hang?
On a side note, this code does not hang the gc_term():
import std.stdio;
class A
{
B b;
bit isDeleting;
~this()
{
isDeleting=1;
if(!b.isDeleting)
delete b;
}
}
class B
{
A a;
bit isDeleting;
~this()
{
isDeleting=1;
if(!a.isDeleting)
delete a;
}
}
void main()
{
A a=new A;
B b=new B;
a.b=b;
b.a=a;
delete a;
}
Which is odd. For some reason, mutually calling dtors doesn't cause the
dtors to stick in an infinite loop, but it causes gc_term() to. But even
though the classes have the same structure in this example, and their
pointers to one another have the same values (null), gc_term() doesn't hang.

Hi,
"delete a;" will also set a to null, so you can't delete it twice, hence
no loop..
I'm not sure about gc_term, though, but I think it's first a bug that
you try to delete a twice (once from main, once from b)...
xs0
Jarrett Billingsley wrote:

Out of curiosity, I wrote this:
import std.stdio;
class A
{
B b;
~this()
{
delete b;
writefln("a dtor: ",cast(void*)b);
}
}
class B
{
A a;
~this()
{
delete a;
writefln("b dtor: ",cast(void*)a);
}
}
void main()
{
A a=new A;
B b=new B;
a.b=b;
b.a=a;
delete a;
fflush(stdout);
}
I expected it to get caught in an infinite loop between the two dtors, but
surprisingly, all that is printed is
a dtor: 0
b dtor: 0
But then, the program hangs in gc_term().
What is happening here? Why don't the objects get caught in an infinite
loop between their dtors? And if they're no longer pointing to one another
after they are dtor'ed (but most likely not GCed), why does gc_term() hang?
On a side note, this code does not hang the gc_term():
import std.stdio;
class A
{
B b;
bit isDeleting;
~this()
{
isDeleting=1;
if(!b.isDeleting)
delete b;
}
}
class B
{
A a;
bit isDeleting;
~this()
{
isDeleting=1;
if(!a.isDeleting)
delete a;
}
}
void main()
{
A a=new A;
B b=new B;
a.b=b;
b.a=a;
delete a;
}
Which is odd. For some reason, mutually calling dtors doesn't cause the
dtors to stick in an infinite loop, but it causes gc_term() to. But even
though the classes have the same structure in this example, and their
pointers to one another have the same values (null), gc_term() doesn't hang.

Hi,
"delete a;" will also set a to null, so you can't delete it twice, hence
no loop..
I'm not sure about gc_term, though, but I think it's first a bug that you
try to delete a twice (once from main, once from b)...

But "delete a" in main() will not set the 'a' member of 'B' to null; only
the reference to 'a' in main() gets nullified. Meaning that you can call
delete twice on 'a', although the second time, it has already been deleted
and is still sitting in memory, not yet GCed.
In fact, here's another example that causes gc_term() to hang.
import std.stdio;
class A
{
~this()
{
writefln("a dtor");
}
}
void main()
{
A a=new A;
A a2=a;
delete a;
writefln("a: ",cast(void*)a);
writefln("a2: ",cast(void*)a2);
delete a2;
writefln("a2: ",cast(void*)a2);
fflush(stdout);
}
It seems that calling delete on an object twice (though it should really
never happen) makes gc_term() hang. I don't know why.