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?

+3


source to share


2 answers


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.

+3


source


Because as your quote says, it's only undefined behavior if it has a non-trivial destructor or deallocation function. If it is incomplete, the compiler does not know if this is the case, so it does not know if the program is well defined.



+5


source







All Articles