문제

This one made me think:

class X;

void foo(X* p)
{
    delete p;
}

How can we possibly delete p if we do not even know whether X has visible destructor? g++ 4.5.1 gives three warnings:

warning: possible problem detected in invocation of delete operator:
warning: 'p' has incomplete type
warning: forward declaration of 'struct X'

And then it says:

note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.

Wow... are compilers required to diagnose this situation like g++ does? Or is it undefined behavior?

도움이 되었습니까?

해결책

From the standard [expr.delete]:

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.

So, it's UB if there's nontrivial stuff to do, and it's ok if there isn't. Warnings aren't neccessary for UB.

다른 팁

It is undefined behavior.

However, you can make the compiler check for incomplete types, like boost:

// verify that types are complete for increased safety

template<class T> inline void checked_delete(T * x)
{
    // intentionally complex - simplification causes regressions
    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
    (void) sizeof(type_must_be_complete);
    delete x;
}

Applying sizeof to an incomplete type should trigger an error, and I suppose if that passes with some compiler, then an array of negative size would trigger an error.

It is undefined behaviour, and a common gotcha when implementing the pImpl pattern. To the best of my knowledge, there is simply no such thing as a warning that the compiler is required to emit. Warnings are elective; they're there because the compiler writer thought they would be useful.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top