TDPL: Manual invocation of destructor

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Mon Aug 9 13:57:12 PDT 2010


Lutger wrote:
> Andrei Alexandrescu wrote:
> 
>> Lutger wrote:
>>> Steven Schveighoffer wrote:
>>>
>>>> On Mon, 09 Aug 2010 08:28:38 -0400, Andrej Mitrovic
>>>> <andrej.mitrovich at gmail.com> wrote:
>>>>
>>>>> It's rather perplexing, isn't it? It states in TDPL:
>>>>>
>>>>> "After you invoke clear, the object is still alive and well, but its
>>>>> destructor has been called and the object is now carrying its
>>>>> default-constructed stated. During the next garbage collection, the
>>>>> destructor is called again, because the garbage collector has no idea in
>>>>> what state you have left the object."
>>>> This seems totally wrong, what if an object has no default constructor?
>>>> The spec used to say (maybe it still does) that a destructor is guaranteed
>>>> to only ever be called once.
>>> The spec still does, it is not updated since it describes delete, not clear.
>>>
>>> If you omit the default constructor, no constructor will be called. Also not
>>> for the base classes even if they have a default constructor. This looks like
>>> a bug.
>> Yes, not calling the constructors of base classes is an implementation
>> bug. If a class does not define any constructor at all, it has a de
>> facto default constructor. If a class does define some constructor but
>> not a parameterless one, it is a bug in the implementation if clear()
>> compiles.
>>
>>> Confusingly, if an object has a default constructor but is constructed from
>>> anything else, clear will still call the default constructor.
>> I think that's reasonable. Otherwise the object would have to remember
>> in a hidden state variable which constructor it was initialized from.
> 
> The confusing part (to me) comes from the special role of the default 
> constructor in the current scheme. You cannot use clear() to release a resource 
> constructed with it because it is immediately acquired again and hold onto until 
> (if at all) the collector decides to collect it. Not to mention it is acquired 
> twice. It seems to be unsuitable for acquiring an (expensive) resource and yet 
> that is exactly what tdpl illustrates.  

The default constructor for classes already has a special role, e.g. 
it's the only one known polymorphically and the only one used by the 
built-in object factory.

If someone acquires a resource in the default constructor, one can 
presume that all other constructors also allocate that resource so 
ownership of the resource is part of the object's invariant. 
Consequently, the destructor can assume ownership of the resource. If 
clear() initializes the object by bitblitting the initial values over 
the object's fields, then the later-invoked destructor will fail.

>>> I reckon it is
>>> also surprising if you later insert a previously omitted default constructor
>>> that the behavior can change a lot, especially when base classes are
>>> involved.
>> That's a consequence of the implementation bugs above, I think.
>>
>>
>> Andrei
> 
> Thanks, that will help with the other points. Should I file bugs?

Yes please.


Andrei


More information about the Digitalmars-d mailing list