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
delete
a 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_ptr
is 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_ptr
is an example where it isn't a problem (in general). That's because the constructor ofboost::shared_ptr
stores a deleter function, and the complete type of the pointee must necessarily be known at the point of construction.Cheers & hth.,