digitalmars.D.learn - destructors and GC again
- Lutger (12/12) Oct 16 2006 Sorry for this topic again, I'm still not exactly sure: when an
- Derek Parnell (19/33) Oct 16 2006 I don't think that it is guaranteed. You need to either explicitly delet...
- Lutger (21/57) Oct 16 2006 Really? That would be so foobar. I'm trying to rewrite my half-broken
- Sean Kelly (6/11) Oct 16 2006 When an object is collected by the GC, it's dtor will be called.
- Lutger (12/26) Oct 16 2006 Good, the possibly not collecting part is no problem.
- Carlos Santander (20/34) Oct 16 2006 There's also the problem with global objects:
- Derek Parnell (17/54) Oct 16 2006 Yes, this is my experience too. It also happens with objects stored in A...
- Carlos Santander (4/45) Oct 16 2006 Of course, but sometimes "tmp" has to be global, so it's not good all th...
- Derek Parnell (11/55) Oct 16 2006 What do you mean? Doesn't "global" mean that the variable needs to be
- Jarrett Billingsley (8/12) Oct 16 2006 If "A tmp" is declared at global scope, writing "auto tmp = new A" in ma...
Sorry for this topic again, I'm still not exactly sure: when an unreferenced object is collected during the lifetime of your program (before main exits), is the destructor of this object guaranteed to be called? I expect it to be so, as otherwise destructors seem pretty useless (and dangerous), but cannot infer this from the spec. The spec says: "The garbage collector is not guaranteed to run the destructor for all unreferenced objects ... The garbage collector calls the destructor function when the object is deleted." It's not clear from this to me that IF an object is collected (of which you cannot be sure, ok), what is guaranteed about the destructor. I assume 'deleted' in the spec means that delete is explicitly called, not 'collected by the GC'.
Oct 16 2006
On Mon, 16 Oct 2006 16:36:52 +0200, Lutger wrote:Sorry for this topic again, I'm still not exactly sure: when an unreferenced object is collected during the lifetime of your program (before main exits), is the destructor of this object guaranteed to be called? I expect it to be so, as otherwise destructors seem pretty useless (and dangerous), but cannot infer this from the spec. The spec says: "The garbage collector is not guaranteed to run the destructor for all unreferenced objects ... The garbage collector calls the destructor function when the object is deleted." It's not clear from this to me that IF an object is collected (of which you cannot be sure, ok), what is guaranteed about the destructor. I assume 'deleted' in the spec means that delete is explicitly called, not 'collected by the GC'.I don't think that it is guaranteed. You need to either explicitly delete it or use 'auto' (meaning RAII this time). e.g. void somefunc() { auto MyClass X = new MyClass(); } or void somefunc() { MyClass X = new MyClass(); scope(exit) { delete X; } } -- Derek Parnell Melbourne, Australia "Down with mediocrity!"
Oct 16 2006
Derek Parnell wrote:On Mon, 16 Oct 2006 16:36:52 +0200, Lutger wrote:Really? That would be so foobar. I'm trying to rewrite my half-broken signal-slots lib, the C-heap hack I have figured out. (Cannot use auto for this). But I think I need such a guarantee for destructors. This is sort of what I want to achieve: 1. Store a delegate from a member function in C-heap to be used as a callback, so this callback won't prevent GC from collecting the object the callback is taken from. 2. At some point this object is collected by GC. 3. Now the stored callback should be removed, otherwise invoking the callback later in time is a no-no of course. This is done from the destructor of the collected object. If 3) is not guaranteed to occur (before main exits, after that it doesn't matter), then I don't see a way to garbage collect these callbacks, which leaves me with the following options: a) don't use the C-heap and just leak memory which the user must manually clean up. b) rely on the user to call delete, avoiding GC altogether. (not a good idea) Both options are not very satisfying, and perhaps even defy the point of such a library. Maybe I'm missing something here?Sorry for this topic again, I'm still not exactly sure: when an unreferenced object is collected during the lifetime of your program (before main exits), is the destructor of this object guaranteed to be called? I expect it to be so, as otherwise destructors seem pretty useless (and dangerous), but cannot infer this from the spec. The spec says: "The garbage collector is not guaranteed to run the destructor for all unreferenced objects ... The garbage collector calls the destructor function when the object is deleted." It's not clear from this to me that IF an object is collected (of which you cannot be sure, ok), what is guaranteed about the destructor. I assume 'deleted' in the spec means that delete is explicitly called, not 'collected by the GC'.I don't think that it is guaranteed. You need to either explicitly delete it or use 'auto' (meaning RAII this time). e.g. void somefunc() { auto MyClass X = new MyClass(); } or void somefunc() { MyClass X = new MyClass(); scope(exit) { delete X; } }
Oct 16 2006
Lutger wrote:Sorry for this topic again, I'm still not exactly sure: when an unreferenced object is collected during the lifetime of your program (before main exits), is the destructor of this object guaranteed to be called? I expect it to be so, as otherwise destructors seem pretty useless (and dangerous), but cannot infer this from the spec.When an object is collected by the GC, it's dtor will be called. However, the GC may not detect an orphaned object as collectable if there is a value in memory somewhere that "looks" like a reference to that object. Sean
Oct 16 2006
Sean Kelly wrote:Lutger wrote:Good, the possibly not collecting part is no problem. It would make more sense to me if these sentences in the spec were different: Spec: "The garbage collector is not guaranteed to run the destructor for all unreferenced objects" My interpretation: "The garbage collector is not guaranteed to collect all unreferenced objects" Spec: "The garbage collector calls the destructor function when the object is deleted." My interpretation: "The garbage collector calls the destructor function when the object is collected."Sorry for this topic again, I'm still not exactly sure: when an unreferenced object is collected during the lifetime of your program (before main exits), is the destructor of this object guaranteed to be called? I expect it to be so, as otherwise destructors seem pretty useless (and dangerous), but cannot infer this from the spec.When an object is collected by the GC, it's dtor will be called. However, the GC may not detect an orphaned object as collectable if there is a value in memory somewhere that "looks" like a reference to that object. Sean
Oct 16 2006
Sean Kelly escribió:Lutger wrote:There's also the problem with global objects: //------------------------------------------- import std.stdio; class A { ~this() { writefln("~A"); } } A tmp; void main() { tmp=new A; } //------------------------------------------- Nothing is printed. -- Carlos Santander BernalSorry for this topic again, I'm still not exactly sure: when an unreferenced object is collected during the lifetime of your program (before main exits), is the destructor of this object guaranteed to be called? I expect it to be so, as otherwise destructors seem pretty useless (and dangerous), but cannot infer this from the spec.When an object is collected by the GC, it's dtor will be called. However, the GC may not detect an orphaned object as collectable if there is a value in memory somewhere that "looks" like a reference to that object. Sean
Oct 16 2006
On Mon, 16 Oct 2006 15:34:22 -0500, Carlos Santander wrote:Sean Kelly escribió:Yes, this is my experience too. It also happens with objects stored in AA's I think. However, either of these fix the issue. void main() { auto tmp=new A; } . . . . void main() { auto tmp=new A; scope(exit) { delete tmp; } } -- Derek Parnell Melbourne, Australia "Down with mediocrity!"Lutger wrote:There's also the problem with global objects: //------------------------------------------- import std.stdio; class A { ~this() { writefln("~A"); } } A tmp; void main() { tmp=new A; } //------------------------------------------- Nothing is printed.Sorry for this topic again, I'm still not exactly sure: when an unreferenced object is collected during the lifetime of your program (before main exits), is the destructor of this object guaranteed to be called? I expect it to be so, as otherwise destructors seem pretty useless (and dangerous), but cannot infer this from the spec.When an object is collected by the GC, it's dtor will be called. However, the GC may not detect an orphaned object as collectable if there is a value in memory somewhere that "looks" like a reference to that object. Sean
Oct 16 2006
Derek Parnell escribió:On Mon, 16 Oct 2006 15:34:22 -0500, Carlos Santander wrote:Of course, but sometimes "tmp" has to be global, so it's not good all the time. -- Carlos Santander BernalThere's also the problem with global objects: //------------------------------------------- import std.stdio; class A { ~this() { writefln("~A"); } } A tmp; void main() { tmp=new A; } //------------------------------------------- Nothing is printed.Yes, this is my experience too. It also happens with objects stored in AA's I think. However, either of these fix the issue. void main() { auto tmp=new A; } . . . . void main() { auto tmp=new A; scope(exit) { delete tmp; } }
Oct 16 2006
On Mon, 16 Oct 2006 20:08:30 -0500, Carlos Santander wrote:Derek Parnell escribió:What do you mean? Doesn't "global" mean that the variable needs to be accessible until main() (or any module dtor for the 'main' module) exits? Thus this is also okay ... static ~this() { delete tmp; } -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 17/10/2006 11:32:08 AMOn Mon, 16 Oct 2006 15:34:22 -0500, Carlos Santander wrote:Of course, but sometimes "tmp" has to be global, so it's not good all the time.There's also the problem with global objects: //------------------------------------------- import std.stdio; class A { ~this() { writefln("~A"); } } A tmp; void main() { tmp=new A; } //------------------------------------------- Nothing is printed.Yes, this is my experience too. It also happens with objects stored in AA's I think. However, either of these fix the issue. void main() { auto tmp=new A; } . . . . void main() { auto tmp=new A; scope(exit) { delete tmp; } }
Oct 16 2006
"Derek Parnell" <derek nomail.afraid.org> wrote in message news:1iii9n8i8lu91.pvgnflxb8mfc$.dlg 40tude.net...What do you mean? Doesn't "global" mean that the variable needs to be accessible until main() (or any module dtor for the 'main' module) exits?If "A tmp" is declared at global scope, writing "auto tmp = new A" in main() will not initialize it. It makes a local variable named "tmp" whose type is automatically deduced. Unless that's not what you were getting at at all..Thus this is also okay ... static ~this() { delete tmp; }Yes, that works well. That's basically what I do to free any and all globally held resources (or those which are static members of classes, which are held in the same data segment I guess).
Oct 16 2006