An idea to avoid a narrow class of bugs

Christophe Travert travert at phare.normalesup.org
Mon Jun 25 07:45:33 PDT 2012


Alex Rønne Petersen , dans le message (digitalmars.D:170622), a écrit :
> On 25-06-2012 15:27, Christophe Travert wrote:
>> Alex Rønne Petersen , dans le message (digitalmars.D:170616), a écrit :
>>>>
>>>> To me, it is a GC implementation issue. You should be able to allocate
>>>> in destructors.
>>>
>>> Yes, I don't understand why on earth this limitation is in place. There
>>> is no (good) technical reason it should be there.
>>
>> Allowing safe unwinding of the stack when throwing exceptions is not a
>> 'good' reason ?
>>
>> Well, a destructor should rather be no_throw, and should be able to
>> call no_throw (GC) functions.
>>
> 
> I fail to see how this is a problem. The GC (read: finalizer thread) 
> simply has to catch the exception and Do Something Meaningful with it.
> 


I confused two dinstict issues concerning destructors:

  - 1/ during GC, the GC may collect data in any order. References in a 
collected object may be invalid. This is not specific to GC usage in 
destructors however.

Example:
struct B
{
  string x;
  ~this()
  {
    writeln('Deleting ', x);
  }
}
struct A
{
  B* b;
  ~this()
  {
    writeln('About to Delete ', b.x); // error since b may have been 
                                      // deleted before this A instance.
    GC.free(b); // should be fine, GC.free has no effect on already 
                // deallocated block
  }
}

=> Using a maybe dead reference should be forbidden in destructor: 
Problem: it is in the general case impossible to tell if A.b has been 
allocated from the GC or not at compile time. However, somebody trying 
to collect GC data in a destructor is likely to ignore that the data may 
already have been collected. I reckon it is legitimate to collect GC 
data from a destructor (provided issue 2 is handled).

  - 2/ When an exception is thrown, destructors are called to unwind the 
stack until the exception is caught. If destructors start to trigger 
exceptions, things can get really messy.

=> It is a good idea to make destructors no_throw (and as stupid and 
simple as possible).

Maybe there is a third issue that motivate bearophile's post.

-- 
Christophe


More information about the Digitalmars-d mailing list