Destructor nonsense on dlang.org

foobar foo at bar.com
Thu May 24 12:46:04 PDT 2012


On Thursday, 24 May 2012 at 17:57:11 UTC, Steven Schveighoffer 
wrote:
> On Thu, 24 May 2012 13:47:31 -0400, Tove <tove at fransson.se> 
> wrote:
>
>> On Thursday, 24 May 2012 at 17:06:19 UTC, ponce wrote:
>>> I really had a hard time to believe it when #D told me so, 
>>> but there is no guaranteed order of destruction and as you 
>>> cannot relies on members still being alive in a class 
>>> destructor.
>>> All of it can happen when making absolutely no cycles in the 
>>> object graph.
>>>
>>> What I do now is having a close function for each class which 
>>> hold a non-memory resource.
>>>
>>> This is writtent in TDPL, but I wish I was told earlier :)
>>
>> http://dlang.org/class.html#destructors
>>
>> "This rule does not apply to auto objects or objects deleted 
>> with the DeleteExpression, as the destructor is not being run 
>> by the garbage collector, meaning all references are valid."
>>
>> i.e. non gc resources are fine... and it's also fine if you 
>> call clear()... it's only a problem if you rely on automatic 
>> collection and reference a object... so there's no need for 
>> close, as clear() will do the trick.
>
> There's a big problem with this though.  Your destructor *has 
> no idea* whether it's being called from within a collection 
> cycle, or from clear.  You must assume the most restrictive 
> environment, i.e. that the dtor is being called from the GC.
>
> This is even true with struct dtors!
>
> -Steve

Looks to me like an issue with separation of concerns. I think 
that dtors need to only provide deterministic management of 
resources and not affect GC algorithms:
1. classes should *not* have dtors at all.
2. struct values should *not* be gc managed [*].

Composition of classes and structs should be handled as follows:
1. If a class contains a pointer to a struct it doesn't scan it 
in a GC cycle. The runtime can provide a hook so that structs 
could register a callback for RC purposes.
2. When a class contains a strcut value, they share the same 
lifetime thus the GC will call the struct's dtor when the object 
is collected.
3. If a struct contains a reference to an object (class instance) 
than *that* object instance is scanned by the GC.

[*] point 3 above means that struct pointers are scanned in a 
pass-thru way only for the purpose of scanning contained object 
references.

With the above semantics, the dtor does know that all its members 
(except for class references) are valid, including any pointers 
to other structs and has similar semantics to c++ dtors. This 
scheme can be enforced by the compiler and is safe since objects 
won't inherently hold any resources by themselves (they don't 
have dtors). This also allows to implement more advanced 
finalization schemes (e.g. dependencies between resources).



More information about the Digitalmars-d mailing list