Destructors vs. Finalizers
Moritz Maxeiner via Digitalmars-d
digitalmars-d at puremagic.com
Wed Jul 26 02:29:15 PDT 2017
On Wednesday, 26 July 2017 at 02:58:00 UTC, Mike Parker wrote:
> Regarding the issue with `destroy` not being @nogc, I my
> understanding is it comes down to `rt_finalize` not being
> @nogc. I haven't dug too deeply into the discussions around it,
> but I'm wondering if it's possible to separate the concept of
> destruction from finalization in the implementation?
Possible, yes, and I agree that separating destruction
(deterministic end of object lifetime) and finalization (GC
collection caused end of object lifetime) for classes is
something we should do.
>
> Externally, we can do it with the existing language:
>
> class {
> ~this() {} // Finalizer
>
> ~this @nogc {} // Destructor
> }
As class destructors (in contrast to class finalizers) are then
called exclusively in a deterministic fashion, there's no reason
to forbid them from allocating using the GC, so I don't think
using the @nogc attribute would be appropriate; I would much
rather see another attribute in the likes of @disable, e.g.
@deterministic, so
---
~this() {} // Finalizer
~this() @nogc {} // Finalizer
~this @deterministic {} // Destructor
~this @nogc @deterministic {} // Destructor
}
---
>
> Internally, the runtime will treat each differently. an
> rt_destruct would call all every __dtor in a hierarchy
As long as finalizers are then not part of __dtor.
> and rt_finalize would be changed to call every __finalizer (a
> new addition) in a hierarchy.
> When cleaning up, the GC will ensure that all destructors are
> run where they exist, followed by all finalizers.
Having the GC directly call destructors defeats the point of
separating them from finalizers in the first place: If a
destructor should be run on GC finalication, the finalizer must
manually call the destructor (using e.g. `destroy`).
The GC must *never* call destructors automatically after
splitting off finalizers, because that would turn destructors
back into finalizers.
> And destroy would be changed to call rt_destruct instead of
> rt_finalize.
Yes, that would then be the correct behaviour for `destroy`.
More information about the Digitalmars-d
mailing list