[cfe-dev] operator delete[] does not call derived class destructor

M.E. O'Neill oneill at cs.hmc.edu
Mon May 21 00:55:51 PDT 2012

Florian Weimer wrote:
>> [...] How can the compiler know where that last element is.  It does know that the array has three things in it, but it can't use n*sizeof(Base) to calculate the value it needs, which is n*sizeof(Derived).
> The element size could be written next to the place where the number of elements is stored.

Doing that would violate a core principle of C++, which is "you don't pay for what you don't use", since it would add overhead for every array created with new.  Most people wouldn't use this feature, yet would have to pay for it.

In fact (as I understand it), early in the design of C++, new didn't stash the array size and you had remember it yourself and then pass it into delete (inside the square brackets).  Although Stroustrup changed it pretty quickly to the design we know today because people hated that hassle, I think the original design would have been more true to the C++ philosophy.

> Or it could be derived from the vtable pointer (which is the same for all the elements).  Probably not without ABI changes, though.

Yes, we can imagine the type_info struct containing size information, but that would still increase the per-class overhead of RTTI, and as we just saw in another thread, some people build with -fno-rtti just to avoid the overhead we have now.

Myself, I'd love it it C++ had better run-time metadata about types, even if it were only optional and only enabled with -fmore-rtti-please.  As things stand right now, the only way to introspect in a meaningful way is to either (a) use facilities intended for the debugger, or (b) adopt a coding convention that hand-supplies the necessary metadata, duplicating information clang already knows.  I don't like (b) on principle.

FWIW, as an example of applying strategy a to the problem at hand, you can can use LLDB's SBType::GetByteSize, as in the enclosed code.  Getting from a typeid to an SBType inside the original program is left as an exercise for the reader.



# Look up a type in the debugging information.  No error checking.
import lldb
import sys
prog,type = sys.argv[1:3]
debugger = lldb.SBDebugger.Create()
target = debugger.CreateTargetWithFileAndArch (prog, lldb.LLDB_ARCH_DEFAULT)
desiredtype = target.FindTypes(type).GetTypeAtIndex(0);
print desiredtype
print "---> size is", desiredtype.GetByteSize()

unix% clang -g -o badcode badcode.cpp
unix% python typeinfo.py badcode Base
class Base {
    virtual void ~Base();
---> size is 8
unix% python typeinfo.py badcode Derived
class Derived : public Base {
    int stuff_;
    virtual void ~Derived();
---> size is 16

More information about the cfe-dev mailing list