views:

111

answers:

1
+3  Q: 

delete expression

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;
}
+5  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 used std::auto_ptr). boost::shared_ptr is an example where it isn't a problem (in general). That's because the constructor of boost::shared_ptr stores a deleter function, and the complete type of the pointee must necessarily be known at the point of construction.

Cheers & hth.,

Alf P. Steinbach
Yes. It was my overlook. Updated it
Chubsdad
+1, interesting. Does this ever actually happen, that it's necessary to delete a POD type without having its definition? Aren't classes with trivial destructors the least likely to be left incomplete? Hmfph.
Potatoswatter
can you please provide a reference to the article/material that you mentioned on gotw?
Chubsdad
Alf P. Steinbach
@Chubsdad: additional info: even as it's presented now it's still formally Undefined Behavior, but with the constructor and destructor of the public class defined in the implementation file it will in practice work with most and probably all compilers. The earliest version I can find, from 2001, still had a forward reference to GOTW 62, so I don't think the original is archived.
Alf P. Steinbach