[Date Prev][Date Next][Thread Prev][Thread Next][Author Index][Date Index][Thread Index]

"delete", "destroy", "reclaim", and "p->Heaper::~Heaper();"



Date: Tue, 14 Aug 90 09:14:21 PDT
   From: xanadu!michael (Michael McClary)

   > From: vlad!mark (Mark S. Miller)
   > 
   > (Although I'm still curious about what happens if a member destructor
   > BLASTs--is it as bad as if a member constructor BLASTs?)

   ... If the destructor which BLASTS
   is the destructor of a superclass, ...

Perhaps the phrase "member destructor" isn't clear.  Consider:

CLASS(FooVar,Var) {
  PUBLIC:
    ...
    ~FooVar()
    {
	if (...) {
	    BLAST(....);
	}
    }
};

CLASS(Bar,Baz) {
    ...
  PRIVATE:
    FooVar foo;
};


During the destruction of a Bar, the foo member's destructor is
implicitly called.  This happens between the time that the code in
Bar's destructor executes, and Baz's destructor executes.  It is the
exact analogue (with time reversed) of what happens with member
constructors.  You've explained previously why having member
constructors BLAST causes unfixable problems with the Bomb package.  I
was just wondering if we had the corresponding problem on the
destruction side.  In particular, is the vtable set to Bar or Baz, and
would either result in a non-fatal situation?  (My guess would be that
this is unfixable under either answer)  


   ... An object may be serving more than one client, and wish
   to transparently refuse destruction unless it's the last client that
   makes the request.  ...

   ... Your solution of providing a conventional member function
   whose semantics is conditional destruction, and reserving the destructor
   for actually destroying the object, is great stuff.

My "More later" is hereby retracted.  You've done quite a good job of
figuring out and explaining what my concerns were.  Thank you.

   The only semantic problem with BLASTING from destruction is that it may
   result in an object of a superclass type being held by a pointer to one
   of its subclasses.  This presents essentially the same case as holding a
   pointer that has been incorrectly cast to a derived type: ...

Until you pointed it out, the type unsafety of BLASTing out of
destructors never occured to me.  Quite dangerous stuff!  In fact,
this is sufficiently dangerous that I'd like to tentatively propose
the following (opinions definitely solicited): 

We have the Heaper::destroy() method detect if any BLASTs escape the
"delete this;", and abort the program with a fatal error if they do.
Therefore the default assumption is that a client who's just doing
things the normal way is unprepared to be careful enough to handle a
destructor BLAST.  We should also code our objects so that in general
we are confident (with eventual X4Ref help) that BLASTs cannot
actually escape destructors.  It is already the case if an object does
an uncaught BLAST when it is being destructed by the garbage collector
(by "p->Heaper::~Heaper()") that this is necessarily a fatal error.

For those rare cases where an object needs to BLAST during
destruction, and its clients have been carefully coded to deal with
it, this can be denoted by having the object provide a "destroy"-like
method (which does a "delete this;" without the BLAST check), and
having this careful client call it instead.  This method should not be
declared up in Heaper, but only in those rare classes where it is
appropriate.