gpt4 book ai didi

c++ - 对不完整类型的空指针调用 delete 是否合法?

转载 作者:IT老高 更新时间:2023-10-28 22:04:20 33 4
gpt4 key购买 nike

如果是这样,为什么下面的代码会给我警告

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

?

struct C;

int main()
{
C *c = nullptr;

delete c;

return 0;
}

理解如果 C 有非平凡的/虚拟的析构函数,为什么它可能在一般情况下是未定义的行为,但没有无论情况如何,标准保证/定义 nullptr 上的 delete 始终是 noop

重申一下:我特别询问指向不完整类型的指针是 nullptr!

的情况

最佳答案

标准说 ([expr.delete]/5):

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.

所以如果 T有一个重要的析构函数或有一个 operator delete重载,你得到UB。关于 UB 基于指针的(即:它是否为空指针)没有任何说明。


关于“对象被删除”是什么意思?

可以认为“对象被删除”意味着该子句仅适用于 delete调用实际对象。因此,如果你传递一个空指针,它就不适用。

首先,关于 delete 行为的标准讨论的其余部分明确指出其行为不适用于空指针。 [expr.delete]/6&7 都以“如果删除表达式的操作数的值不是空指针值”开头。第 5 段明确不包含这些词。因此,我们必须假设它确实适用于空指针。

其次,如果传递一个空指针,“对象被删除”的含义是什么?毕竟那里没有“对象”。

好吧,考虑一下如果“正在删除的对象”专门讨论该指针末尾的对象,那么解释此文本意味着什么。那么,如果您要删除具有非平凡析构函数的不完整类数组会发生什么?

按照这种逻辑,无论指针是否为空,此子句都不适用。为什么?因为“被删除的对象”是 array 类型,而不是类类型。因此,该条款不能适用。这意味着编译器必须能够调用 delete[]在一组不完整的类上。

但这不可能实现;这将要求编译器能够追踪尚不存在的代码。

因此,“正在删除的对象”旨在引用 std::remove_pointer_t<std::decay_t<decltype(expr)>> ,或者标准要求的行为是不可能实现的。标准措辞可能会稍微清理一下,将“如果正在删除的对象在删除点具有不完整的类类型”替换为“如果 T 是指向 U 的指针或 U 的数组,并且U 在删除点具有不完整的类类型,..."

关于c++ - 对不完整类型的空指针调用 delete 是否合法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47353696/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com