deleting destructors

scott douglass sdouglass at arm.com
Fri Sep 20 14:51:05 UTC 2002


Hi,

I have a question about delete destructors (D0).  Must they handle being passed a null this pointer?  The ABI document doesn't seem to address this.  I would guess the answer is: "D0 destructors that represent non-virtual destructors must handle this == 0.  D0 destructors that represent virtual destructors may assume this != 0."

In general the ABI document seems to assume the reader understands the basics of the responsibilites of C1/C2/C3 and D0/D1/D2.  It does go into sufficient gory detail about VTTs in 3.3.1 but having some more basic information would be nice.  For example, I know that in-charge constructors must construct all virtual bases and not-in-charge constructors must not -- but I don't think the ABI says so (but I could have missed it).

I also believe that for a class with no virtual bases the C1 and C2 constructors have identical effect (and similarly for the D1 and D2 destructors).  So when constructing (destructing) a base or member subobject that has no virtual bases either constructor (destructor) may be used.

Here's some psuedo-code that reflects my understand.  Have I got it right?

void T::T{C1}(void* this, ...user args...) { // in-charge (aka complete object)
  ... construct virtual bases, if any ...
  T::T{C2}(this[, T::VTT], ...user args...);
}

void T::T{C2}(void* this[, VTT* vtt], ...user args...) { // in-charge (aka subobject)
  ... construct non-virtual base subobjects, if any ...
  ... construct member subobjects, if any ...
  ... user code ...
}

T* T::T{C3}(...user args...) { // allocating
  T* this = operator new(sizeof(T));
  T::T{C1}(this, ...user args...);
  return this;
}

void T::~T{D0}(T* this) { // deleting
  if (this != 0) { // not needed if T::~T is virtual
    T::~T{D1}(this);
    operator delete(this); // or operator delete(this, sizeof(T));
  }
}

void T::~T{D1}(T* this) { // in-charge (aka complete object)
   T::~T{D2}(this[, T::VTT]);
   ... destruct virtual base subobjects, if any ...
}

void T::~T{D2}(T* this[, VTT* vtt]) { // in-charge (aka subobject)
   ... user code ... // user returns must be specially handled
   ... destruct member subobjects, if any ...
   ... destruct non-virtual base subobjects, if any ...
}


Very minor nit:  The ABI document uses both "sub-object" and "subobject" which make searching it a bit harder.  The C++ Standard use "subobject".




More information about the cxx-abi-dev mailing list