删除null void*指针是不确定的行为?

Xeo*_*Xeo 28 c++ void-pointers null-pointer undefined-behavior language-lawyer

我知道delete空指针是一个无操作:

在任一替代方案中,如果delete的操作数的值是空指针,则操作无效.
(C++标准5.3.5 [expr.delete] p2)

并且删除void*指针是未定义的行为,因为无法调用析构函数,因为没有类型的对象void:

在第一个alternative(delete object)中,delete的操作数的值应该是指向非数组对象的指针或指向表示这种对象的基类的子对象的指针.如果不是,则行为未定义.
(C++标准5.3.5 [expr.delete] p2)

现在,通常我认为列出的东西首先列出了后面列出的东西,但是空void*指针如下呢?

void* p = 0;
delete p; // UB or well-defined?
Run Code Online (Sandbox Code Playgroud)

APr*_*mer 12

我想知道如何只有在它为空时才能找到删除指针的情况.但保持语言律师模式......

在C++ 03中

5.3.5/1

delete的操作数应具有指针类型或具有到指针类型的单个转换的类类型.

void*是一个指针类型,因此null void指针符合静态要求.

5.3.5/2

在替代[ deletedelete[]]中,如果delete的操作数的值是空指针,则操作无效.

这给出了想要的行为.

5.3.5/3

在第一个替代(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义.

这不相关,空指针不引用要检查其他约束的对象.

在C++ 0X中

5.3.5/1

操作数应具有指向对象类型的指针,或具有指向对象类型的指针的单个非显式转换函数(12.3.2)的类类型.

void*不是指向对象类型的指针,因此应该被拒绝.


Naw*_*waz 8

§5.3.5/ 3说,

在第一个替代(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义.在第二个备选(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义73

在脚注中,它说,

73 - 这意味着无法使用void*类型的指针删除对象,因为没有void类型的对象.

它是啊,它的UB.

现在一旦它进入未定义行为的城市,无论它是否为空无关紧要,因为它的行为不能保持精确定义,因为它已经在未定义行为的城市居住.


编辑:

得到另一个主题也引用相同的并说它的UB:

删除void指针是否安全?

  • @Nawaz:我没看到你的帖子的相关性**.:-) (2认同)
  • 这里没有对象,那句话是无关紧要的。 (2认同)