删除不完整类型的对象

时间:2010-12-01 14:06:24

标签: c++ pointers forward-declaration delete-operator incomplete-type

这个让我想到:

class X;

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

如果我们甚至不知道delete p是否有可见的析构函数,我们怎么可能X? g ++ 4.5.1给出了三个警告:

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

然后它说:

  

注意:析构函数和类特定运算符都不会删除   将被调用,即使它们是在定义类时声明的。

哇......像g ++一样诊断这种情况需要编译器吗?还是未定义的行为?

3 个答案:

答案 0 :(得分:21)

来自标准[expr.delete]:

  

如果要删除的对象有   不完整的类型   删除和完整的类有一个   非平凡的析构函数或者   解除分配函数,行为是   未定义。

所以,如果有非常重要的事情要做,那就是UB,如果没有,那就没关系。 UB不需要警告。

答案 1 :(得分:6)

这是未定义的行为。

但是,您可以让编译器检查不完整的类型,例如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;
}

sizeof应用于不完整类型会触发错误,我想如果它通过某些编译器传递,那么负数大小的数组会触发错误。

答案 2 :(得分:3)

这是未定义的行为,是实现pImpl模式时常见的问题。据我所知,根本不需要编译器需要发出的警告。警告是选修课;他们在那里是因为编译器编写者认为它们会很有用。