Referring to objects of incomplete class type, also known as forward declarations, is a common practice. One such common usage is with the "pimpl idiom" [Sutter 00] whereby an opaque pointer is used to hide implementation details from a public-facing API. However, attempting to delete a pointer to an object of incomplete class type can lead to undefined behavior. The C++ Standard, [expr.delete], paragraph 5 , states [ISO/IEC 14882-2014], states:
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.
...
Pointer downcasting (casting a pointer to a base class into a pointer to a derived class) may require adjusting the address of the pointer by a fixed amount that can be determined only when the layout of the class inheritance structure is known. In this noncompliant code example, f()
retrieves a polymorphic pointer of complete type B
from getD()
. That pointer is then cast to a pointer of incomplete type D
before being passed to g()
. Casting to a pointer to the derived class may fail to properly adjust the resulting pointer, causing causing undefined behavior when the pointer is dereferenced by calling d->doSomething()
.
...
[ISO/IEC 14882-2014] | 5.3.5, "Delete" |
[Sutter 00] | "Compiler Firewalls and the Pimpl Idiom" |
[Dewhurst 03] | Gotcha 39, "Casting Incomplete Types" |
...