Why is the deletion of an incomplete type defined as "undefined behaviour"?
From the C++ specification; §5.3.5/5;
If the object being deleted has incomplete class type at the point of deletion and the complete class has a non-trivial destructor or a deallocation function, the behavior is undefined.
Given the code example (I understand why it is an error);
class ABC;
int main()
{
ABC* p = nullptr;
delete p;
}
Why is it defined as being undefined behaviour when gcc, clang and msvc all warn on it being an incomplete type? Why not just error at that point, i.e. why is it not a diagnosable error?
Because, as your quote says, it's only undefined behaviour if it has a non-trivial destructor or deallocation function. If it's incomplete, the compiler doesn't know whether or not that's the case, so doesn't know whether or not the program is well-defined.
The expression delete p;
does two things:
*p
.Item 2 may be possible when all you know is the address of the object, without any further information. The memory allocator only cares about addresses. But determining the complete object's address may be difficult; you essentially need to promise that you are actually providing the address of a complete object.
But there's more. Before deallocating the object's storage, you must run destructors (Item 1). If the destructor has no effect, then it is acceptable to not run destructors, since that has the same behaviour as if you did run them. But if running destructors does have an effect, omitting Item 1 leads do undefined behaviour, and you need to know the complete type in order to know how to run destrutors. Incidentially, you also need to know the complete type in order to determine the address of the most-derived object for Item 2.
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