在C ++ 03标准中,我看到:
5.3.5删除
2如果操作数具有类类型,则通过调用上述转换函数将操作数转换为指针类型,并使用转换后的操作数代替本节其余部分的原始操作数。 在任一替代方案中,如果
delete
的操作数的值是空指针,则操作无效。在第一个备选方案(删除对象)中,delete
的操作数的值应该是指向非数组对象的指针或指向表示这种对象的基类的子对象(1.8)的指针(第10节)。如果不是,则行为未定义。在第二个备选方案(删除数组)中,delete
的操作数的值应该是由前一个数组new-expression得到的指针值.72)如果不是,则行为是未定义。
在C ++ 11 Draft Standard(N3337)中,我看到:
5.3.5删除
2如果操作数具有类类型,则通过调用上述转换函数将操作数转换为指针类型,并使用转换后的操作数代替本节其余部分的原始操作数。在第一个替代方法(删除对象)中,
delete
的操作数的值可能是空指针值,指向创建的非数组对象的指针通过先前的 new-expression ,或指向表示此类对象的基类的子对象(1.8)的指针(第10条)。如果不是,则行为未定义。在第二种方法(删除数组)中,delete操作数的值可以是空指针值或由前一个数组 new-expression 产生的指针值。如果不是,则行为未定义。
我已经强调了两个标准中规范之间的差异。我觉得奇怪的是,2003标准更加强调必须如何处理NULL指针,而2011标准没有说明实现必须做什么。
C ++ 11标准的措辞是否在草案标准和实际标准之间发生了变化?如果是这样,怎么样?
如果标准草案的措辞在实际标准中保持不变,那么在2003年和2011年之间将一份非常强烈的声明改为几乎没有任何理由的理由是什么?
答案 0 :(得分:25)
我们可以在defect report 348中找到这种变化的理由,其中说:
具体而言,标准在5.3.5 [expr.delete]第2段中说:
...如果delete的操作数的值是空指针,则操作无效。
标准未指定术语“无效”。目前尚不清楚 这个上下文,是否需要调用deallocation函数 没有效果,或者delete-expression不应该调用deallocation 功能
此外,在第4段标准中说明了默认的释放功能:
如果delete-expression调用实现释放 function(3.7.4.2 [basic.stc.dynamic.deallocation]),如果是的操作数 delete表达式不是空指针常量,...
为什么默认的释放函数和delete-expr的交互如此具体?
如果“无效”是对释放功能的要求,那么 它应该在3.7.4.2 [basic.stc.dynamic.deallocation]中说明,或者在 18.6.1.1 [new.delete.single]和18.6.1.2 [new.delete.array],应该明确说明。
决议的一部分是你注意到的措辞的变化,尽管围绕这种措辞的语言已经发生了很大的变化,但是摆脱的逻辑没有效果语言仍然存在,它不是一个定义明确的术语,因此应该用明确的语言替换。
答案 1 :(得分:10)
最新的C ++ 14草案(N3797)与本节中的措辞大致相同。但是这种行为同样具有强烈的指定性,而不是完全相同的段落。
如果delete-expression的操作数值不为null 指针值,delete-expression将调用析构函数(如果 any)对象或被删除数组的元素。在里面 在数组的情况下,元素将按顺序销毁 减少地址(即,完成的相反顺序) 他们的建设者;看到 12.6.2)。
如果delete-expression的操作数值不为null 指针值,然后: - 如果分配调用new-expression 没有省略要删除的对象( 5.3.4),delete-expression应调用deallocation函数( 3.7.4.2)。从new-expression的分配调用返回的值应作为第一个参数传递给 释放功能。 - 否则,delete-expression不会 调用释放函数( 3.7.4.2)。
这些段落显然与C ++ 03一样强大。委员会不可能打破delete
无效指针的程序的行为,因为这些程序很普遍,而且修复的成本太大了。这将使C ++ 11无法实现。