Destructors vs. Finalizers
Steven Schveighoffer via Digitalmars-d
digitalmars-d at puremagic.com
Wed Jul 26 17:00:08 PDT 2017
On 7/26/17 7:28 PM, Moritz Maxeiner wrote:
> On Wednesday, 26 July 2017 at 22:33:23 UTC, Steven Schveighoffer wrote:
>> On 7/26/17 2:33 PM, Moritz Maxeiner wrote:
>>> On Wednesday, 26 July 2017 at 17:38:28 UTC, Dgame wrote:
>>>> I don't get it. The GC collects the objects which aren't in use
>>>> anymore. The order in which this is currently happening is not
>>>> specified. So, how are the destructors supposed to be called in the
>>>> right order? Manually? ARC?
>>>
>>> After the split:
>>> Destructors are only for deterministic end of object lifetime, so
>>> yes, they are to be called by any scheme (such as manual management
>>> via destroy and reference counting - which is likely also implemented
>>> as calling destroy) that is deterministic.
>>> Finalizers are for nondeterministic schemes such as the GC.
>>> The GC *never* calls destructors directly, only finalizers.
>>> A finalizer might manually call a destructor, but a destructor may
>>> never call a finalizer.
>>
>> Actually, it's the opposite.
>
> It's a matter of definition and this is the behaviour I would define,
> because
>
>> A finalizer can never call anything on its members because it doesn't
>> know if it's being destroyed by the GC.
>
> This falsely assumes that all members point into the GC pool.
Yes, I should have qualified GC members.
> A
> finalizer may freely work on non-pointer members and pointer members
> that target objects outside the GC pool which the programmer knows to be
> valid at finalization (e.g. they are manually managed).
> Whether or not it makes sense for the finalizer to call the destructor
> is something the programmer has to decide on a per use case basis.
No, because a destructor can safely assume it can look at GC members'
data. So a finalizer can never call it.
>>
>> The destructor is ensured that the entire structure is intact, so it
>> can do whatever it wants.
>
> The point is that I saw (and see) no reason for a destructor to ever
> call a finalizer.
An example:
class File
{
int fd;
ubyte[] buffer;
// avoiding bikeshed issues by using clear names
destructor() { finalizer(); delete buffer; }
finalizer() { close(fd); }
}
No reason to repeat the finalizer code in the destructor.
-Steve
More information about the Digitalmars-d
mailing list