删除 nullptr 可能会也可能不会调用释放函数。为什么不保证后者呢?

Dr.*_*Gut 3 c++ compiler-optimization language-lawyer delete-operator

C++20 标准说(参见[expr.delete]

如果删除表达式的操作数的值为空指针值,则未指定是否将如上所述调用释放函数。

cppreference.com 说(请参阅删除表达式

如果表达式计算结果为空指针值,则不会调用析构函数,并且可能会或可能不会调用释放函数(未指定),但保证默认释放函数在传递空指针时不执行任何操作。

如果删除表达式的操作数为 null,为什么编译器会调用释放函数?

如果可以保证不会调用释放函数,则规则会更简单,但我认为标准允许这样做是有充分理由的。


提案:我认为delete ptr;应该指定为与此等效:

if (ptr) {
   // call dtor.
   // call deallocation function
}
Run Code Online (Sandbox Code Playgroud)

如果ptr已知为空或不为空,我们就会进行相应的优化。释放函数会假设它们的参数不为空,因此不会!= nullptr发生双重检查。

我认为这个更简单。

Chr*_*isB 6

从历史的角度来看,过去的标准是这样说的:c++03 \xc2\xa75.3.5/2

\n
\n

[...]如果delete操作数的值为空指针,则该操作无效。

\n
\n

这个措辞被发现有问题并引发了缺陷报告

\n
\n

标准没有指定术语“无效”。从上下文中尚不清楚,是否要求调用的释放函数不起作用,或者删除表达式不应调用释放函数。

\n
\n

由于编译器以不同的方式解释旧的、不明确的措辞(请参阅此示例,其中 GCC 7.5 和 clang 7.0 对于是否插入此检查有冲突的意见),因此不指定它是最兼容的决定。

\n

从优化器的角度来看,这也是优选的,因为它可以根据情况提供优化机会,例如:

\n
    \n
  • 如果这是常见情况,请插入空检查以避免函数调用,
  • \n
  • 如果已知指针值为空,则省略函数调用,
  • \n
  • 如果已知指针值不为空,则删除检查。
  • \n
\n