Thread overview
Destructors calling sequence
Nov 29, 2013
Temtaime
Nov 29, 2013
Temtaime
Nov 29, 2013
bearophile
Nov 29, 2013
Adam D. Ruppe
Nov 29, 2013
Ali Çehreli
Nov 29, 2013
Maxim Fomin
Nov 29, 2013
Temtaime
Nov 30, 2013
Michael
November 29, 2013
Hi !
http://dpaste.dzfl.pl/53d9a59e

How i can enforce that ~A will be called after ~B ?

I'm writing 3D engine and it's critical to me.

Thanks for yours aid !
November 29, 2013
Please, don't advise to call b.destroy.
November 29, 2013
Temtaime:

> How i can enforce that ~A will be called after ~B ?
> I'm writing 3D engine and it's critical to me.

The GC doesn't give such guarantees. So you need something manual, or to use RAII, or scope(exit), or some other idea like creating an array of objects to be destroyed, etc.

Bye,
bearophile
November 29, 2013
In this specific case, you can force a collection at the end of main()


void main() {
	auto b = new B;
	a = new A;

	import core.memory;
	GC.collect();
}

The gc runs automatically at the end of the program, but at that point, both b and a are gone, so the gc just gets to it as soon as it can. Manually calling collect after you're done with b but before the program ends (so a is still in use) it should do it in order.

But, generally, if you want to rely on destructors at all, you have to use structs, or at least destroy(). They might never run with classes and the order is undefined - it all depends on when and if the GC ever actually grabs it.

Thought a struct at module scope might never run its destructor at all...
November 29, 2013
On 11/29/2013 08:58 AM, Adam D. Ruppe wrote:

> In this specific case, you can force a collection at the end of main()
>
>
> void main() {
>      auto b = new B;
>      a = new A;
>
>      import core.memory;
>      GC.collect();
> }

Note that the OP requires the unusualy destruction order: b first.

In any case, these objects can be destroyed without destroy anyway.

    mixin("dest" ~ /* :p */ "roy(a);");

Ali

November 29, 2013
On Friday, 29 November 2013 at 16:48:58 UTC, Temtaime wrote:
> Hi !
> http://dpaste.dzfl.pl/53d9a59e
>
> How i can enforce that ~A will be called after ~B ?
>
> I'm writing 3D engine and it's critical to me.
>
> Thanks for yours aid !

It is impossible to do this directly given current gc implementation, but you can do something like that:

class A
{
   bool reset;
   void delegate dtor();
   ~this()
   {
      if (!reset)
         dtor();
   }
}

class B
{
   A a;
   bool run;
   ~this() { if (!run) a.reset = true; run = true; }
}

A a = new A;
B b = new B;
b.a = a;
b.a.dtor = & b.__dtor;
November 29, 2013
I see.
Thanks for all for yours replies !
November 30, 2013
> class A
> {
>    bool reset;
>    void delegate dtor();
>    ~this()
>    {
>       if (!reset)
>          dtor();
>    }
> }
>
> class B
> {
>    A a;
>    bool run;
>    ~this() { if (!run) a.reset = true; run = true; }
> }
>
> A a = new A;
> B b = new B;
> b.a = a;
> b.a.dtor = & b.__dtor;

relying on to "bool reset" it's no good idea.

In this case a manual memory management - good choice.