TDPL: Manual invocation of destructor

bearophile bearophileHUGS at lycos.com
Tue Aug 10 05:27:19 PDT 2010


Andrei Alexandrescu:
> class File {
>      FILE * fp;
>      this() { fp = fopen("/tmp/temporary"); }
>      ~this() { fclose(fp); }
> }

I am not expert enough about all this topic, so I try to keep myself out of this discussion. Recently I have read this:

>issues with finalizers. The main problem with finalizers and garbage collection is that finalizers generally try to reclaim a non-memory resource (such as a specific file, a file handle, or a network socket) based purely on a memory reclamation policy (generally triggered by later memory allocations). Generally those other resource exhaust well before memory does, then you're out of the resource stuck waiting for garbage collection to notice a particular finalizer needs to be run. A better general rule of thumb is "don't ever use finalizers". Instead always call close inside a finally.<

This means that putting something like a fclose(fp) inside the ~this() is wrong, you need to add a specific method to that File class to ask for the closing of the file, because you generally can't rely on the GC for this, because a GC is free to even never collect objects, if there is enough RAM.

In my opinion it's correct to put something like a fclose(fp) inside the ~this() only if you are sure this struct/class will be always allocated on the stack, so its destructor will always be called deterministically when the scope ends (a reference counting strategy too seems acceptable, because it is deterministic).

In a GC-based language you can't assume your destructors are run, so your destructors usually need to be empty, and you need to add other methods to free explicitly and manually (or with a scope(exit)) all the resources that aren't RAM.

Please take this cum grano salis, I am not an expert on this.

Bye,
bearophile


More information about the Digitalmars-d mailing list