【问题标题】:Is it still safe to delete nullptr in c++0x?在 c++0x 中删除 nullptr 是否仍然安全?
【发布时间】:2011-10-07 13:29:56
【问题描述】:

c++03 中,很明显删除空指针没有任何效果。事实上,§5.3.5/2 中明确指出:

在任一替代方案中,如果 delete 的操作数的值为空指针,则该操作无效。

但是,在当前的draftc++0x 中似乎缺少这句话。在草稿的其余部分,我只能找到说明如果 delete-expression 的操作数不是空指针常量会发生什么的句子。是否删除了c++0x中仍然定义的空指针,如果是,在哪里?

注意事项:

有重要的间接证据表明它仍然是明确定义的。

首先,§5.3.5/2中有两句话说明

在第一种选择(删除对象)中,delete的操作数的值可能是一个空指针值,...

在第二种选择(删除数组)中,delete的操作数的值可以是空指针值或者...

这些说允许操作数为空,但它们本身并没有真正定义如果它是会发生什么。

其次,更改delete 0 的含义是一项重大的重大更改,标准委员会不太可能做出此特定更改。此外,在c++0x 草案的兼容性附件(附件 C)中没有提及这是一项重大更改。然而,附录 C 是一个信息性部分,因此这与标准的解释无关。

另一方面,删除空指针必须无效,这意味着额外的运行时检查。在很多代码中,操作数永远不能为空,因此这种运行时检查与零开销原则相冲突。也许委员会只是决定改变行为以使标准 c++ 更符合语言的既定设计目标。

【问题讨论】:

    标签: c++ null language-lawyer delete-operator


    【解决方案1】:

    5.3.5/7 说:

    如果 delete-expression 的操作数的值不是空指针值,则 delete-expression 将调用释放函数 (3.7.4.2)。否则,未指定是否调用释放函数。

    3.7.4.2/3 说:

    提供给释放函数的第一个参数的值可能是空指针值;如果是这样,并且如果释放函数是标准库中提供的函数,则调用无效。

    所以行为是很好定义的,只要使用标准的释放函数,或者用户提供的释放函数正确处理空指针。

    【讨论】:

    • Since C++14 "如果表达式求值为空指针值,则不调用析构函数,也不调用释放函数。"
    • @Wormer 我认为该页面不正确。当指针为空(5.3.5/7)时,C++14 标准仍然说“未指定是否会调用释放函数”。
    • 顺便说一句,为空文件指针调用 fclose() 是安全的。在 Ubuntu(可能还有其他操作系统)上, fclose(NULL) 会导致分段错误。
    【解决方案2】:

    另一方面,删除空指针必须无效这一事实意味着额外的运行时检查。

    新措辞不会删除空指针的运行时检查。反过来说:标准草案更接近于说实现必须使空指针测试符合要求。

    另外值得注意的是:旧标准自相矛盾,它说(5.3.5/2)“如果 delete 的操作数的值是空指针,则操作无效”,但后来又说(5.3.5 /7) “删除表达式将调用释放函数。”调用函数是一种效果。尤其如此,因为被调用的函数很可能是被覆盖的operator delete

    新的措辞消除了这种矛盾,明确地让实现在删除空指针的情况下是否调用释放函数。

    【讨论】:

      猜你喜欢
      • 2021-10-27
      • 2012-02-18
      • 2013-06-04
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 2010-10-07
      • 2011-06-23
      • 1970-01-01
      相关资源
      最近更新 更多