digitalmars.D.learn - When is a class's destructor called?
- Mike (66/66) Dec 28 2013 I'm trying to implement a very minimal D runtime for the ARM
- Mike Parker (4/6) Dec 28 2013 Class destructors are not called when an object goes out of scope. They
- Mike (8/18) Dec 28 2013 Ok, I understand that, but since I don't have a garbage
- bearophile (5/7) Dec 29 2013 The garbage collector doesn't know that.
- ponce (12/19) Dec 29 2013 If you want deterministic destruction, you have plenty of choices:
- Dicebot (14/14) Dec 29 2013 Also destructors are not guaranteed to be run by D specification.
- Mike (3/11) Dec 29 2013 Do you happen to know of any clever technique to make object, and
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (4/14) Dec 29 2013 There is std.typecons.RefCounted:
- bearophile (5/11) Dec 29 2013 I think it only works on a single object, not on the whole tree.
- Mike (2/15) Dec 29 2013 Yep, and it's a struct, so no inheritance.
- Dicebot (3/6) Dec 29 2013 Patch compiler to make all classes scope classes. But that won't
I'm trying to implement a very minimal D runtime for the ARM Cortex-M platform. I've been quite successful so far, but I'm now getting into reference types and I need to understand better what D does under the hood. I have a working malloc/free implementation, but don't have a garbage collector. I'm not yet sure if I want a garbage collector, so at the moment, I'm trying to implement something simple. Consider the following code modeled after the example at http://dlang.org/memory.html#newdelete: ************************************* class X { __gshared uint _x; new(size_t nBytes) { Trace.WriteLine("Constructing"); void* p; p = malloc(nBytes); if (p == null) { //TODO: //throw new OutOfMemoryError(); } return p; } ~this() { Trace.WriteLine("Destructor"); } delete(void* p) { if (p != null) { free(p); } Trace.WriteLine("Destroying"); } } void DoX() { X x = new X(); x._x = 123; Trace.WriteLine(x._x); //Why doesn't x's destructor get called here. } //My entry point void main() { DoX(); Trace.WriteLine("Done"); while(true) { } } ************************************** The output is as follows: ------------------------------ Constructing 56 Done x's destructor never gets called. What do I need to implement to have the destructor called when x goes out of scope? I'm using GDC 4.8 cross-compiled for arm-none-eabi on a Linux 64-bit host. Thanks, Mike
Dec 28 2013
On 12/29/2013 2:03 PM, Mike wrote:x's destructor never gets called. What do I need to implement to have the destructor called when x goes out of scope?Class destructors are not called when an object goes out of scope. They are called by the garbage collector only when memory needs to be reclaimed or during the cleanup cycle during app shutdown.
Dec 28 2013
On Sunday, 29 December 2013 at 06:53:08 UTC, Mike Parker wrote:On 12/29/2013 2:03 PM, Mike wrote:Ok, I understand that, but since I don't have a garbage collector, what must I implement to call the destructor when it goes out of scope? Another way of asking the question is: How does the garbage collector know when something has gone out of scope and is therefore safe to collect? And where is that implemented in the runtime?x's destructor never gets called. What do I need to implement to have the destructor called when x goes out of scope?Class destructors are not called when an object goes out of scope. They are called by the garbage collector only when memory needs to be reclaimed or during the cleanup cycle during app shutdown.
Dec 28 2013
Mike:How does the garbage collector know when something has gone out of scopeThe garbage collector doesn't know that. Look in Wikipedia how a Mark&Sweep GC works. Bye, bearophile
Dec 29 2013
Ok, I understand that, but since I don't have a garbage collector, what must I implement to call the destructor when it goes out of scope? Another way of asking the question is: How does the garbage collector know when something has gone out of scope and is therefore safe to collect? And where is that implemented in the runtime?If you want deterministic destruction, you have plenty of choices: - scoped! - using structs instead - scope(exit) - RefCounted! - Unique! - ... Yet using classes for ressources is not composable. It's either: - using classes for the convenience and deal with resource release manually - using structs It's an open quesiton for me which choice is best.
Dec 29 2013
Also destructors are not guaranteed to be run by D specification. It is perfectly legal to skip such cleanup step upon program termination. http://dlang.org/class.html#destructors : "The garbage collector is not guaranteed to run the destructor for all unreferenced objects. Furthermore, the order in which the garbage collector calls destructors for unreference objects is not specified. This means that when the garbage collector calls a destructor for an object of a class that has members that are references to garbage collected objects, those references may no longer be valid. This means that destructors cannot reference sub objects. 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."
Dec 29 2013
On Sunday, 29 December 2013 at 10:16:33 UTC, ponce wrote:If you want deterministic destruction, you have plenty of choices: - scoped! - using structs instead - scope(exit) - RefCounted! - Unique! - ...Do you happen to know of any clever technique to make object, and everything that inherits from it, a referenced counted object?
Dec 29 2013
On 12/29/2013 04:00 AM, Mike wrote:On Sunday, 29 December 2013 at 10:16:33 UTC, ponce wrote:There is std.typecons.RefCounted: AliIf you want deterministic destruction, you have plenty of choices: - scoped! - using structs instead - scope(exit) - RefCounted! - Unique! - ...Do you happen to know of any clever technique to make object, and everything that inherits from it, a referenced counted object?
Dec 29 2013
Ali Çehreli:On 12/29/2013 04:00 AM, Mike:I think it only works on a single object, not on the whole tree. (And I think RefCounted is not used often in D.) Bye, bearophileDo you happen to know of any clever technique to make object, and everything that inherits from it, a referenced counted object?There is std.typecons.RefCounted:
Dec 29 2013
On Sunday, 29 December 2013 at 14:24:05 UTC, bearophile wrote:Ali Çehreli:Yep, and it's a struct, so no inheritance.On 12/29/2013 04:00 AM, Mike:I think it only works on a single object, not on the whole tree. (And I think RefCounted is not used often in D.) Bye, bearophileDo you happen to know of any clever technique to make object, and everything that inherits from it, a referenced counted object?There is std.typecons.RefCounted:
Dec 29 2013
On Sunday, 29 December 2013 at 06:58:03 UTC, Mike wrote:Ok, I understand that, but since I don't have a garbage collector, what must I implement to call the destructor when it goes out of scope?Patch compiler to make all classes scope classes. But that won't be D anymore.
Dec 29 2013