destructors

Bill Baxter dnewsgroup at billbaxter.com
Tue May 1 07:31:00 PDT 2007


Daniel Keep wrote:
> 
> Daniel Giddings wrote:
>> Bill Baxter wrote:
>>> Is this ok in D?
>>>
>>>
>>> class MyClass
>>> {
>>>    OtherClass a;
>>>    this() {
>>>       a = new OtherClass;
>>>    }
>>>    ~this() {
>>>       delete a;
>>>    }
>>> }
>>>
>>> I was just trying to fix the crash on exit in the tinyXPath code on
>>> dsource, and it does the above a lot.
>>>
>>> --bb
>> I would expect that to work (it is something I would want to be able to
>> do - otherwise you would need a finalise method - yuck), I can't recall
>> if I have done it though?
>>
>> a should still be detected as having objects referencing it until the
>> MyClass destructor is finished I would think (if the delete a wasn't
>> there). Otherwise you would not be able to rely on any class properties
>> as still existing in its destructor (ie a.method() could cause an
>> exception as well).
> 
> Exactly.  You can't.
> 
> Long story short is thus: the *only* thing you can say for sure still
> exists when your destructor is called, is your own object's memory.
> Look at it like this:
> 
>> class ObjPtr
>> {
>>     ObjPtr obj;
>>     this(ObjPtr obj = null) { this.obj = obj; }
>>     ~this() { ... }
>> }
>>
>> auto a = new ObjPtr;
>> auto b = new ObjPtr(a);
>> auto c = new ObjPtr(b);
>>
>> c = null;
>> gc.fullCollect();
> 
> Question: what order do the objects get destroyed in?
> Answer: no one knows.
> 
> The problem is that in order for the GC to destroy objects in "the right
> order", it would have to build a complete dependency graph between the
> various objects, then destroy them in the right order.
> 
> But what happens if you've got a *lot* of objects, or those objects
> don't care what order they're destroyed in, or worse: cycles.  If you've
> got cycles, the GC is stuffed, and there *is* no correct order to
> destroy them in.
> 
> There was a thread quite some time ago that demonstrated a hacked
> version of phobos that allowed destructors to take a bool argument that
> told the destructor if the object was being destroyed deterministically
> (ie: via the delete statement, or because the object was scoped) or not.
>  Sadly, it never caught on :(

That makes a lot of sense.  Why can't it just say that in the 
documentation?  "In the presenence of cycles, it is impossible to ensure 
that parent objects are always deleted before the children they refer to."

Ok, so we can say that generally speaking, any D code that contains a 
'delete member;' in the destructor is bad code.  Right?

The exceptions mentioned in the doc are scope classes (well the doc says 
"auto" but  I think it means old-school auto, aka "scope", because you 
know that's not going away because of a GC sweep.).  And also anything 
else you know is getting explicitly deleted is ok... except there's no 
way to *know* if you're being explicitly deleted so you have to assume 
you're not.

--bb


More information about the Digitalmars-d-learn mailing list