Dan*_* M. 18 c++ nullptr language-lawyer delete-operator incomplete-type
如果是这样,为什么下面的代码会给我警告
注意:即使在定义类时声明析构函数也不会调用析构函数或特定于类的运算符delete
?
struct C;
int main()
{
C *c = nullptr;
delete c;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我明白为什么它会在一般情况下是不确定的行为,如果C有非平凡/虚析构函数,但不标准的保证/定义delete上nullptr始终是一个noop不管情况如何?
重申:我具体询问指向不完整类型的指针的情况nullptr!
Nic*_*las 16
标准说([expr.delete]/5):
如果被删除的对象在删除时具有不完整的类类型,并且完整的类具有非平凡的析构函数或释放函数,则行为是未定义的.
因此,如果T有一个非平凡的析构函数或有一个operator delete过载,你得到UB.关于UB基于指针的值(即:它是否为空指针)没有任何说法.
可以认为"删除对象"意味着该子句仅适用于delete对实际对象的调用.因此,如果传递空指针,则不适用.
首先,关于delete显式行为的其余标准讨论调用了它的行为不适用于空指针.[expr.delete]/6&7都以"如果delete-expression的操作数的值不是空指针值"开头.第5段明确地不包含这些词.因此,我们必须假设它确实适用于空指针.
第二,如果传递空指针,"被删除对象"的含义是什么?毕竟,那里没有"对象".
好吧,如果"被删除的对象"具体谈到该指针末尾的对象,请考虑解释此文本意味着什么.那么,如果您使用非平凡的析构函数删除一组不完整的类,会发生什么?
根据该逻辑,该子句不适用,无论指针是否为空.为什么?因为"被删除的对象"是数组类型,而不是类类型.因此,本条款不适用.这意味着编译器必须能够delete[]在不完整的类数组上调用.
但这是不可能实现的; 它需要编译器能够跟踪尚不存在的代码.
所以,无论是"被删除的对象"是意指std::remove_pointer_t<std::decay_t<decltype(expr)>>,或标准要求的行为是不可能实现的.标准的措辞可能会被清理一下,取而代之的是"如果正在删除的对象在删除时具有不完整的类类型",则"如果T是指针U或数组U,并且U在删除时具有不完整的类类型" ,......"
| 归档时间: |
|
| 查看次数: |
1755 次 |
| 最近记录: |