Why is an incomplete type exception defined as "undefined behavior"?
Why is deletion of an incomplete type defined as "undefined behavior"?
From the C ++ specification; ยง5.3.5 / 5;
If the object being deleted is of an incomplete class type at the point of deletion, and the complete class has a non-trivial destructor or deallocation function, the behavior is undefined .
Given the sample code (I understand why this is a bug);
class ABC;
int main()
{
ABC* p = nullptr;
delete p;
}
Why is it defined as undefined behavior when gcc, clang and msvc all warn that it is an incomplete type? Why not just an error at this point, then why is it not a diagnostic error?
source to share
The expression delete p;
serves two purposes:
- Destroy the complete object containing
*p
. - Deallocate memory used to store the specified object.
Item 2 may be possible when all you know is the address of the object, without further information. The memory allocator only cares about addresses. But determining the full address of an object can be difficult; you essentially need to promise that you are actually providing the address of the complete object.
But there is more. Before freeing the storage space of the object, you must run the destructors (point 1). If the destructor has no effect, then it is permissible not to run destructors, as this has the same behavior as if you were running them. But if executing destructors does have an effect, omitting element 1 results in undefined behavior, and you need to know the full type to know how to run destructors. By the way, you also need to know the complete type in order to determine the address of the most derived object for point 2.
source to share