We once had an interview with a very experienced C++ developer who couldn't answer the following question: is it necessary to call the base class destructor from the derived class destructor in C++?
Obviously the answer is no, C++ will call the base class destructor automagically anyway. But what if we attempt to do the call? As I see it the result will depend on whether the base class destructor can be called twice without invoking erroneous behavior.
For example in this case:
class BaseSafe {
public:
~BaseSafe()
{
}
private:
int data;
};
class DerivedSafe {
public:
~DerivedSafe()
{
BaseSafe::~BaseSafe();
}
};
everything will be fine - the BaseSafe
destructor can be called twice safely and the program will run allright.
But in this case:
class BaseUnsafe {
public:
BaseUnsafe()
{
buffer = new char[100];
}
~BaseUnsafe ()
{
delete[] buffer;
}
private:
char* buffer;
};
class DerivedUnsafe {
public:
~DerivedUnsafe ()
{
BaseUnsafe::~BaseUnsafe();
}
};
the explicic call will run fine, but then the implicit (automagic) call to the destructor will trigger double-delete and undefined behavior.
Looks like it is easy to avoid the UB in the second case. Just set buffer
to null pointer after delete[]
.
But will this help? I mean the destructor is expected to only be run once on a fully constructed object, so the optimizer could decide that setting buffer
to null pointer makes no sense and eliminate that code exposing the program to double-delete.
Is the compiler allowed to do that?