为什么删除void *是UB而不是编译错误? [英] Why deleting void* is UB rather than compilation error?

查看:276
本文介绍了为什么删除void *是UB而不是编译错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么通过void*删除对象是未定义的行为,而不是编译错误?

Why would deleting an object through void* be undefined behavior, rather than compilation error?

void foo(void* p) {
    delete p;
}

此代码编译并生成代码,尽管带有gcc和clang的警告(令人惊讶的是,ICC没有给出警告):

This code compiles and produces code, albeit with the warning on gcc and clang (surprisingly, ICC doesn't give a warning):

:2:5:警告:无法删除带有空"指针的表达式 输入'void *'[-Wdelete-incomplete]

:2:5: warning: cannot delete expression with pointer-to-'void' type 'void *' [-Wdelete-incomplete]

为什么不是简单的格式无效的语法无效的程序?看起来Standard并没有花太多时间在[expr.delete]

Why is not simply malformed program with invalid syntax? Looks like Standard doesn't spend too much time on it, saying in [expr.delete] that

这意味着不能使用类型为的指针删除对象 void *,因为void不是对象类型.

This implies that an object cannot be deleted using a pointer of type void* because void is not an object type.

我会因为什么原因而不会触发硬编译错误吗?

Would there be any reason I am missing why this does not trigger a hard compilation error?

推荐答案

在现代C ++中,删除void *指针 的格式不正确(即我们通常所说的编译错误" )

In modern C++ deleting a void * pointer is ill-formed (i.e. it is what we typically call a "compilation error")

8.3.5删除
1 [...]操作数应指向对象类型或类类型的指针.

8.3.5 Delete
1 [...] The operand shall be of pointer to object type or of class type.

void *不是对象类型的指针.

void * is not a pointer to object type.

在C ++ 98中,情况有所不同.删除void *类型的空指针是NOP,而删除void *类型的非空指针则是UB.

In C++98 the situation was different. Deleting a null pointer of void * type was a NOP, while deleting a non-null pointer of void * type was UB.

此规范更改似乎是由缺陷报告#599 .原始规范允许在delete-expression中提供 any 指针类型的空指针,例如函数指针.这看起来是不必要的. DR#599的分辨率提高了要求,同时也禁止了void *.

This change in the specification appears to have been triggered by defect report #599. The original spec allowed supplying null pointers of any pointer type in delete-expression, like function pointers, for example. This looked unnecessarily permissive. The resolution of DR#599 tightened the requirements, outlawing void * as well.

这篇关于为什么删除void *是UB而不是编译错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆