Steven Schveighoffer wrote:
On Mon, 09 Aug 2010 16:31:39 -0400, Andrei Alexandrescu
<[email protected]> wrote:
Steven Schveighoffer wrote:
On Mon, 09 Aug 2010 15:46:27 -0400, Andrei Alexandrescu
<[email protected]> wrote:
Lutger wrote:
Steven Schveighoffer wrote:
On Mon, 09 Aug 2010 08:28:38 -0400, Andrej Mitrovic
<[email protected]> wrote:
It's rather perplexing, isn't it? It states in TDPL:
"After you invoke clear, the object is still alive and well, but its
destructor has been called and the object is now carrying its
default-constructed stated. During the next garbage collection, the
destructor is called again, because the garbage collector has no
idea in
what state you have left the object."
This seems totally wrong, what if an object has no default
constructor?
The spec used to say (maybe it still does) that a destructor is
guaranteed
to only ever be called once.
The spec still does, it is not updated since it describes delete,
not clear. If you omit the default constructor, no constructor
will be called. Also not for the base classes even if they have a
default constructor. This looks like a bug.
Yes, not calling the constructors of base classes is an
implementation bug. If a class does not define any constructor at
all, it has a de facto default constructor. If a class does define
some constructor but not a parameterless one, it is a bug in the
implementation if clear() compiles.
How can this be decided at compile time?
basic counter-example:
class C
{
this(int x) {}
}
// how do you statically disable this?
void foo(Object o)
{
clear(o);
}
void foo(C c)
{
auto c = new C(1);
foo(c);
}
Sorry, I got things mixed.
I always thought clear would simply overwrite the object with it's
default data as defined in the TypeInfo (i.e. before a constructor is
normally called). Calling the constructor is absolutely wrong. We
don't want to reset the object, we want to free it's resources.
Re-constructing it may reallocate resources *THAT WE JUST ASKED TO BE
DESTROYED MANUALLY*. To say clear as defined is a replacement for
delete is complete fantasy.
Well this is my view as well and the original intent of clear(). The
problem is, if someone defined a default constructor, they presumably
have a nontrivial invariant to satisfy. I'm unclear on what's the best
path to take.
Who cares about invariants when an object is destructed?
The destructor itself.
First,
invariants are disabled in release mode.
I was refering to invariant in-the-large, not D's invariant keyword and
associated notion.
I also strongly suggest the destructor only be called once. Having a
destructor called more than once means your destructor has to take into
account that the object may be already destructed. This would be helped
by the same mechanism that would make sure invariants aren't run after
destruction.
If some constructor has been called in between two calls to the
destructor, there's shouldn't be any danger.
Andrei