Thread overview | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 01, 2007 destructors | ||||
---|---|---|---|---|
| ||||
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 |
May 01, 2007 Re: destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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'd be suspect of the delete; unless you explicitly delete an object, you cannot guarantee in what order objects will be destroyed. That means that it's entirely possible that 'a' has already been deleted by the time your dtor runs. <Insert song and dance about how having an implicit/explicit flag passed to dtors would solve this.> -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/ |
May 01, 2007 Re: destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | "Daniel Keep" <daniel.keep.lists@gmail.com> wrote in message news:f171sp$104t$1@digitalmars.com... > > <Insert song and dance about how having an implicit/explicit flag passed to dtors would solve this.> > <Insert song and dance about how having an explicit destruction order would solve this even easier> |
May 01, 2007 Re: destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | 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).
|
May 01, 2007 Re: destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote: > "Daniel Keep" <daniel.keep.lists@gmail.com> wrote in message news:f171sp$104t$1@digitalmars.com... >> <Insert song and dance about how having an implicit/explicit flag passed to dtors would solve this.> >> > > <Insert song and dance about how having an explicit destruction order would solve this even easier> <Via the majesty of interpretive dance, point out that having potential cycles of objects makes that really, really difficult, but that having any kind of solution would be an improvement> -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/ |
May 01, 2007 Re: destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Giddings | 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 :( -- Daniel -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/ |
May 01, 2007 Re: destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | Daniel Keep wrote:
>
> 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 :(
Tango provides a global hook for this. It isn't exactly the same, but it has a similar effect.
Sean
|
May 01, 2007 Re: destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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
|
May 01, 2007 Re: destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Baxter | "Bill Baxter" <dnewsgroup@billbaxter.com> wrote in message news:f17iv3$1s1a$1@digitalmars.com... > Ok, so we can say that generally speaking, any D code that contains a 'delete member;' in the destructor is bad code. Right? Any destructor which uses any reference members in any way is bad code. Thus making destructors nearly worthless for anything but releasing system resources. But even then, I'm not sure if the destructors always get called, especially at the end of the program. |
May 01, 2007 Re: destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | Daniel Keep wrote: > > > 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. Yuck - I never really thought about this. So destructors in D are almost as useless as the __del__ method in Python :-( > 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 :( > > -- Daniel > The bool would be incredibly handy as you'd be able to still do destructor type things safely with explicit deletes. I suppose an alternative would be something like class MyClass { OtherClass a; this() { a = new OtherClass; } MyClass destroy() { delete a; delete this; return null; } // is the return null above ok in D? - it seemed ok when run } then you'd know when its been explicitly deleted. MyClass m = new MyClass; ... m = m.destroy(); |
Copyright © 1999-2021 by the D Language Foundation