删除不完整类型的对象

fre*_*low 25 c++ pointers forward-declaration delete-operator incomplete-type

这个让我想到:

class X;

void foo(X* p)
{
    delete p;
}
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

然后它说:

注意:即使在定义类时声明析构函数也不会调用析构函数或特定于类的运算符delete.

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

eta*_*ion 21

从标准[expr.delete]:

如果被删除的对象在删除时具有不完整的类类型,并且完整的类具有非平凡的析构函数或释放函数,则行为是未定义的.

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

  • 我抚摸出模棱两可的部分.据我所知,标准并没有说删除不完整类型的对象在每种情况下都是UB,正如我引用的部分所述.为什么你认为UB是无条件的?(标准在哪里说这个?) (6认同)
  • 不,它不是"UB if",它是无条件的UB.例如,该类可能在单独的堆上重载`operator new`,而`delete`语句现在将调用错误的`operator delete`. (2认同)

Unc*_*ens 7

这是未定义的行为.

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

应用于sizeof不完整类型应该触发错误,我想如果它通过一些编译器,那么负大小的数组将触发错误.