www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - destructors in global objects

reply "Carlos Santander B." <csantander619 gmail.com> writes:
This program doesn't output anything:

//-------------------------------------------
import std.stdio;

class A
{
     ~this()
     {
         writefln("~A");
     }
}

A tmp;

void main()
{
     tmp=new A;
}
//-------------------------------------------

If tmp is local, then the program (as expected) outputs "~A". There're 
two things I'd like to know about it: first, why? I mean, why does it 
behave like this? Second, the dtor isn't being called, right? Is the 
memory being released? Say A holds a handle to a file, or a socket, or 
something similar. Will it be released/closed/whatever at the end of the 
execution? Assuming the answers to the second issue are affirmative (as 
I hope), how can I prove it? I mean, make tmp do something that I can 
see when it dies.

-- 
Carlos Santander Bernal

JP2, you'll always live in our minds
Apr 13 2005
next sibling parent reply James Dunne <jdunne4 bradley.edu> writes:
Okay, now I know I'm not crazy!  I've witnessed this behavior before when
working on my no-gc phobos patch.  Strange... the documentation says it should
work though!  That, or I read it wrong since I remember it being worded
strangely.

As a temporary fix, declare your class auto and that should work.  Still, I
don't see the point of not calling destructors in non-auto objects; are they
only for auto classes or classes with specific allocators/deallocators?.  If
they're not allowed in normal classes, then make them an error, otherwise make
it work when the object is actually deleted, i.e. at the program termination.

Try a delete call after your new call, see if that makes a difference.

In article <d3klke$2tjq$1 digitaldaemon.com>, Carlos Santander B. says...
This program doesn't output anything:

//-------------------------------------------
import std.stdio;

class A
{
     ~this()
     {
         writefln("~A");
     }
}

A tmp;

void main()
{
     tmp=new A;
}
//-------------------------------------------

If tmp is local, then the program (as expected) outputs "~A". There're 
two things I'd like to know about it: first, why? I mean, why does it 
behave like this? Second, the dtor isn't being called, right? Is the 
memory being released? Say A holds a handle to a file, or a socket, or 
something similar. Will it be released/closed/whatever at the end of the 
execution? Assuming the answers to the second issue are affirmative (as 
I hope), how can I prove it? I mean, make tmp do something that I can 
see when it dies.

-- 
Carlos Santander Bernal

JP2, you'll always live in our minds
Regards, James Dunne
Apr 13 2005
parent "Carlos Santander B." <csantander619 gmail.com> writes:
James Dunne wrote:
 Okay, now I know I'm not crazy!  I've witnessed this behavior before when
 working on my no-gc phobos patch.  Strange... the documentation says it should
 work though!  That, or I read it wrong since I remember it being worded
 strangely.
 
 As a temporary fix, declare your class auto and that should work.  Still, I
 don't see the point of not calling destructors in non-auto objects; are they
 only for auto classes or classes with specific allocators/deallocators?.  If
 they're not allowed in normal classes, then make them an error, otherwise make
 it work when the object is actually deleted, i.e. at the program termination.
 
 Try a delete call after your new call, see if that makes a difference.
I know that works, but that's just like in C, and I'm trying to show that this is unnecesary in D.
 
 Regards,
 James Dunne
-- Carlos Santander Bernal JP2, you'll always live in our minds
Apr 14 2005
prev sibling parent reply "Lionello Lunesu" <lio lunesu.removethis.com> writes:
I think it's a performance optimization: since the OS always releases all 
memory anyway when a program exits, D doesn't do it.

And since it's hard to say when destructors are called (or even IF they are 
called), I think one shouldn't rely on destructors.

L. 
Apr 14 2005
next sibling parent reply James Dunne <jdunne4 bradley.edu> writes:
The assumption is that the class is only allocating memory resources.  This does
not hold for classes that need to release other resources, such as storing back
database information.  It's been said to use auto classes for these cases, but
then I really don't see the point of having/allowing destructors in non-auto
classes in this case at all.

The documentation states that the only time a destructor is really called for a
non-auto class is when the object is deleted by the garbage collector or when an
explicit delete operation is performed on it.  This seems, to me, to defeat the
purpose of a destructor.  The destructor should be guaranteed to be called on
program termination at least.

In article <d3lbms$fg7$1 digitaldaemon.com>, Lionello Lunesu says...
I think it's a performance optimization: since the OS always releases all 
memory anyway when a program exits, D doesn't do it.

And since it's hard to say when destructors are called (or even IF they are 
called), I think one shouldn't rely on destructors.

L. 
Regards, James Dunne
Apr 14 2005
parent reply "Lionello Lunesu" <lio lunesu.removethis.com> writes:
I totally agree with you..

Seems silly to have a function that gets called whenever the GC decides and 
maybe doesn't get called at all.

If, like you say, a destructor becomes invalid for non-auto classes, then 
'auto' should become a property of the class, mentioned when declaring the 
class (not when instantiating, like now).

L. 
Apr 14 2005
parent "Carlos Santander B." <csantander619 gmail.com> writes:
Lionello Lunesu wrote:
 I totally agree with you..
 
 Seems silly to have a function that gets called whenever the GC decides and 
 maybe doesn't get called at all.
 
 If, like you say, a destructor becomes invalid for non-auto classes, then 
 'auto' should become a property of the class, mentioned when declaring the 
 class (not when instantiating, like now).
 
 L. 
 
 
You can declare an auto class: auto class C { } Then all your C objects must be auto too: auto C c; And, if I'm not mistaken, all classes derived from C must be auto too. -- Carlos Santander Bernal JP2, you'll always live in our minds
Apr 14 2005
prev sibling parent reply xs0 <xs0 xs0.com> writes:
Lionello Lunesu wrote:
 I think it's a performance optimization: since the OS always releases all 
 memory anyway when a program exits, D doesn't do it.
 
 And since it's hard to say when destructors are called (or even IF they are 
 called), I think one shouldn't rely on destructors.
 
 L. 
Any objects that get garbage-collected during execution have their dtors called. However, there is no guarantee that they will get collected, and when the program terminates, there is supposedly no need to call dtors, because the OS will clean-up anyway, just like you said. http://www.digitalmars.com/d/class.html#destructors:
 The garbage collector is not guaranteed to run the destructor for
 all unreferenced objects.
xs0
Apr 14 2005
next sibling parent James Dunne <jdunne4 bradley.edu> writes:
In article <d3leu7$ias$1 digitaldaemon.com>, xs0 says...
Lionello Lunesu wrote:
 I think it's a performance optimization: since the OS always releases all 
 memory anyway when a program exits, D doesn't do it.
 
 And since it's hard to say when destructors are called (or even IF they are 
 called), I think one shouldn't rely on destructors.
 
 L. 
Any objects that get garbage-collected during execution have their dtors called. However, there is no guarantee that they will get collected, and when the program terminates, there is supposedly no need to call dtors, because the OS will clean-up anyway, just like you said. http://www.digitalmars.com/d/class.html#destructors:
 The garbage collector is not guaranteed to run the destructor for
 all unreferenced objects.
xs0
xs0, please read my apparently parallel post to yours on this issue ;) Regards, James Dunne
Apr 14 2005
prev sibling parent "Carlos Santander B." <csantander619 gmail.com> writes:
xs0 wrote:
 Lionello Lunesu wrote:
 
 I think it's a performance optimization: since the OS always releases 
 all memory anyway when a program exits, D doesn't do it.

 And since it's hard to say when destructors are called (or even IF 
 they are called), I think one shouldn't rely on destructors.

 L. 
Any objects that get garbage-collected during execution have their dtors called. However, there is no guarantee that they will get collected, and when the program terminates, there is supposedly no need to call dtors, because the OS will clean-up anyway, just like you said.
That's what some have claimed, but it's like I need a proof of that, something visible, that the memory is cleaned up. Also, even if it is cleaned up, the problem with resources (files, sockets, db connections) remain.
 http://www.digitalmars.com/d/class.html#destructors:
  > The garbage collector is not guaranteed to run the destructor for
  > all unreferenced objects.
 
 
 xs0
-- Carlos Santander Bernal JP2, you'll always live in our minds
Apr 14 2005