Class destructors - clarify what is safe

H. S. Teoh hsteoh at qfbox.info
Sat Feb 14 18:42:21 UTC 2026


On Sat, Feb 14, 2026 at 05:36:32PM +0000, Brother Bill via Digitalmars-d-learn wrote:
> On page 325 of Programming in D, we may have a single parameterless
> destructor named ```~this()```.
> 
> A class may have members of string, File, other classes, etc.
> 
> When entering a class destructor, are any of the dynamically allocated
> class members safe to read?

No.  The order in which the GC deallocates objects is not defined, and
when the dtor is run, any references to GC-allocated objects cannot be
safely read, as those objects may have already been destroyed.


> I would expect that a class with strings, FILE handles, etc. would
> need these to do its housekeeping.  If we opened a file in the
> constructor, we should be able to close the file in the destructor.

Files in general would still be valid to read, because they are not
managed by the GC, but by the OS. This is the whole point of dtors.

However, be careful of class wrappers around files.  If your class
references such a wrapper, the wrapper may have already been destructed
by the time your dtor runs, so it's not safe to dereference it.


> As we can explicitly call destroy() on a class instance multiple
> times, do we need to be "careful" of only closing a file once, rather
> than closing a file multiple times, if that can cause issues.

Calling .destroy on a class object more than once may trigger UB.


> What guarantees, if any, exist on entering a class destructor?

Nothing allocated by the GC is guaranteed to be valid when a dtor is
called.  Everything else (e.g. objects allocated by malloc() in libc)
should still be safe to access.

//

Basically, when something is allocated on the GC, the GC takes full
responsibility for managing its lifetime. User code should not try to
intervene.  If your object needs to be managed manually, don't allocate
it from the GC, use C's malloc() or your own memory allocation scheme.
Because of this, class dtors really should not be necessary if you only
allocate objects from the GC.  They are only necessary when you need to
manage resources that are not allocated by the GC, such as OS file
handles, memory allocated by C's malloc(), or other such things.  The
dtor should only take care of cleaning up these external resources, and
should not try to do anything related to GC-allocated objects.


T

-- 
Ignorance is bliss... until you suffer the consequences!


More information about the Digitalmars-d-learn mailing list