Reference here
That destructor will also implicitly
call the destructor of the auto_ptr
object. And that will delete the
pointer it holds, that points to the C
object – without knowing the
definition of C! That appeared in the
.cpp file where struct A’s constructor
is defined.
This was curious and then
5.3.5/5 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.”
My question is that why isn’t such a program which attempts to delete a pointer to an incomplete type treated as ill-formed? Why is it pushed into the realm of conditional (and the complete class has a non-trivial destructor..) ‘undefined behavior’?
What does the ‘and‘ imply?
EDIT 2:
Is the code below well-formed? VS and Gcc/CLang compile, but Comeau gives a warning. I guess all this is part of the undefined behavior mentioned in the Standard. My question is ‘why is this not ill-formed but is undefined’?
#include <iostream>
#include <memory>
using namespace std;
struct C;
// Is this the POI for auto_ptr<C>? $14.6.4.1/3
struct A{
A();
auto_ptr<C> mc;
~A(){} // how does it link to C::~C at this point?
};
struct C{};
A::A():mc(new C){}
int main(){
A a;
}
As I’m writing this your text says “Reference [here][1]” with no reference.
But essentially, the standard allows you to
deletea pointer to incomplete type so that you can leverage knowledge that the compiler doesn’t have, namely that the type’s destructor does nothing.std::auto_ptris an example where this is a problem, especially for the PIMPL idiom (an infamous example of getting it wrong was Herb Sutter’s GOTW on PIMPL, where he incorrectly usedstd::auto_ptr).boost::shared_ptris an example where it isn’t a problem (in general). That’s because the constructor ofboost::shared_ptrstores a deleter function, and the complete type of the pointee must necessarily be known at the point of construction.Cheers & hth.,