在c ++ 0x中删除nullptr是否仍然安全?


84

c++03它是很清楚,删除一个空指针没有任何效果。实际上,明确指出§5.3.5/2

在这两种选择中,如果delete操作数的值为空指针,则该操作无效。

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

笔记:

有大量的间接证据表明它仍然定义明确。

首先,有两个句子§5.3.5/2说明

在第一个替代方案(删除对象)中,删除操作数的值可以为空指针值,...

在第二个替代方案(删除数组)中,删除操作数的值可以为空指针值或...

这些都说操作数被允许为空,但是就其本身而言,实际上并没有定义发生什么情况。

其次,改变的含义delete 0是重大的突破性变化,标准委员会不太可能做出此特定更改。此外,在c++0x草案的兼容性附件(附件C)中没有提到这是一个重大更改。但是,附件C是资料性的部分,因此不涉及本标准的解释。

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

Answers:


101

5.3.5 / 7说:

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

3.7.4.2/3说:

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

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


9
由于C ++ 14 “如果expression的计算结果为空指针值,则不会调用析构函数,也不会调用释放函数。”
沃尔默

2
@Wormer我认为该页面不正确。当指针为null(5.3.5 / 7)时,C ++ 14标准仍然说“未指定是否将调用释放函数”。
interjay

1
顺便说一句,这是不是安全的FCLOSE调用()的一个空文件指针。在Ubuntu(可能还有其他操作系统)上,fclose(NULL)会导致分段错误。
格里·博勒加德

7

另一方面,要求删除空指针无效的事实意味着需要进行额外的运行时检查。

新的措辞不会删除对空指针的运行时检查。相反,标准草案更接近于说一个实现必须进行空指针测试以使其符合要求。

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.