On Fri, 10 May 2013 22:37:43 -0400, Denis Shelomovskij <[email protected]> wrote:

30.04.2013 1:04, "Luís Marques" <[email protected]>" пишет:
This crashes in the last line of main:

     class A
     {
         void foo() {}
     }

     void main()
     {
         A a = new A();
         a.foo();
         clear(a);
         assert(a !is null);
         a.foo();  // crashes
     }

As far as I understand from TDPL book, this should not crash, but it
does (DMD64 v2.062, OS X). Am I misunderstanding clear()?

TDPL states that the object is required to be in a valid state. This necessarily requires calling a constructor on an object, as an object has no valid initial state.

There are major issues with that requirement, though:

1. How to call a ctor for an object that does not have a default ctor? In other words, it requires valid ctor parameters, which the runtime cannot possibly know. 2. What if the ctor adds the class instance to a global or some other rooted memory item? That is, what if the entire point of clearing it is so it was not pointed to as being allocated, so the GC would remove it.

So the decision was made (correctly) to simply make any object that was destroyed be an invalid object. structs will return to their .init value (which may also be invalid depending on the struct).

BTW, why not make clear also change 'a' to null?

That could also be done, but it is superficial:

auto b = a;
destroy(a);
b.foo();

The only valid thing to do with a after destroying it is to stop using it, and all other references to that instance.


Ideally is should throw with pretty message but it isn't implemented. See Issue 8139 - Make objects really disposable by addition of "Object finalized" assertion [1].

IMO, also `destroy` (renamed `clear`) looks like the worst mistake in D runtime and I'd recommend to not use it (or better recompile druntime+phobos without it for your own use). See Issue 9139 - `destroy` is dangerous and inconsistent [2]. Use `unstd.lifetime.finalizeClassInstance` [3] and friends for user-defined lifetime implementation to avoid serious problems.

[1] http://d.puremagic.com/issues/show_bug.cgi?id=8139
[2] http://d.puremagic.com/issues/show_bug.cgi?id=9139
[3] http://denis-sh.github.io/phobos-additions/unstd.lifetime.html#finalizeClassInstance


I'm curious why you think it is bad. All you have said here is that it is bad, not why. Even bug 9139 says "look at how horrible this is" but doesn't explain why.

The point of destroy is to call destructors without deallocation. The original charter said to leave the object in a default state, but that requires re-calling the constructor.

In the latest iteration, it simply calls the finalize function in the runtime. you are not supposed to use it after calling destroy.

Not being defensive, I simply don't understand the objection.

-Steve

Reply via email to