Never called destructor

div0 div0 at users.sourceforge.net
Thu Mar 25 17:37:03 PDT 2010


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Zarathustra wrote:

> Why, in the following piece of code, destructor for 'x' is never called?
> <snip>

Because it is not guaranteed to be called.

http://www.digitalmars.com/d/2.0/class.html#destructors

According to the spec, for the cases you've provided,
you are only guaranteed to see:

Y // for the first case
X // for the second case
<nothing> // at all for the third case.

===

So: (rejigged to remove some pointless statements)

class A{
  string s;
  this(string o_s){
    s = o_s;
  }
  ~this(){
    writefln(s);
  }
}

Case 1:

void main(){
  A y;
  {
    scope x = new A("x");
    y = new A("y");
    x = y;
  } // end scope
}

"scope x", makes the compiler delete the instance held in x when the
end of scope is reached, so you see Y as that is the instance held in x.
The A with "x" is lost to the garbage collector as you reassigned the
reference 'x'.

You don't see x in the output, because the destructor for the instance
with "x" is not guaranteed to be run and in this case it isn't.

Case 2:

void main(){
  A y;
  {
    scope x = new A("x".dup);
    y = new A("y".dup);
  } // end scope
}

see above, "x" is in x this time so you see that deleted.

For *some reason* which is not explained and *can not* be relied upon,
according to the spec, you get a delete of y.

This maybe because the compiler knows through static analysis that both
instances can be deleted.

Case 3:

pretty much the same as 2, but we don't have scope so we aren't
guaranteed to see either destructor. it would be perfectly valid
according to the spec to not see any destructor called at all.

That fact that you see them both called is not easily explainable unless
you have a deep understanding of the compiler and/or the druntime.

I personally would go a bit further and say that you shouldn't see
either destructor called in the third case and shouldn't see a
destructor called for y in the second one.

They aren't guaranteed to be called; so you can't depend on any side
affects; so the druntime should not bother to run a garbage collect on
exit. IIRC in C# apps, you don't see destructors run when you exit.

Deleting & freeing memory when the program is exiting is a complete
waste of time; the OS will reclaim all the memory once your app has died.

- --
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iD8DBQFLrAGvT9LetA9XoXwRAh2NAJ9Pan5WxGQKuNGD7g5QD0kJDgyXAgCeM/gn
TJo7hxdusFTYqC6/oVU4n0w=
=KKLy
-----END PGP SIGNATURE-----


More information about the Digitalmars-d-learn mailing list