According to C++03 12.4/12 when a destructor is invoked explicitly
if the object is not of the destructor’s class type and not of a class derived from the destructor’s class type, the program has undefined behavior
So I have this code:
class Base {};
class Derived : public Base {};
char memory[100];
new(memory) Derived();
Base* ptr = (Base*)memory;
ptr->~Base();
Here the object is of type Derived
and "the destructor's class type" is Base
and so it looks like according to the Standard wording there're no grounds for UB.
So does the code above yield UB according to the Standard?
Correct, there's no undefined behavior.
By contrast there is potential UB in this case depending on the types involved:
Base *ptr = new Derived();
delete ptr;
The reason is that for some types an adjustment might have been applied by the implementation to get from Derived*
to Base*
. So without the pointer to the complete object there's no way to free the memory allocation correctly. A virtual destructor ensures that the Base
sub-object provides enough information for the implementation to recover that (the virtual call mechanism must be able to recover the Derived*
pointer in order to pass it as this
).
But in your example the memory isn't freed and so there's no motivation to make it UB. Of course it's still a bad idea, since conceptually the Derived
object is in a broken state. You have no legitimate way to call ~Derived
, even. In your example though both types are trivially destructible, so there's no need to call the destructor of either.
It's not UB, since both classes have trivial destructors, and therefore calling the destructor has the same effect as not calling the destructor (and not calling the destructor is certainly not UB).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With