为什么通过void*
删除对象是未定义的行为,而不是编译错误?
void foo(void* p) {
delete p;
}
此代码编译并生成代码,尽管gcc和clang上有警告(令人惊讶的是,ICC没有发出警告):
:2:5:警告:无法使用指向''''的指针删除表达式 输入'void *'[-Wdelete-incomplete]
为什么不是简单的格式错误的程序语法无效?看起来标准不会花费太多时间,在[expr.delete]
中说
这意味着无法使用类型指针删除对象 void *因为void不是对象类型。
我有什么理由不知道为什么这不会触发硬编译错误?
答案 0 :(得分:15)
在现代C ++中删除void *
指针 格式错误(即我们通常称之为"编译错误")
8.3.5删除
1 [...]操作数应为指向对象类型或类类型的指针。
void *
不是指向对象类型的指针。
在C ++ 98中,情况有所不同。删除void *
类型的空指针是NOP,而删除void *
类型的非空指针是UB。
规范中的此更改似乎是由defect report #599触发的。原始规范允许在delete-expression中提供任何指针类型的空指针,例如函数指针。这看起来不必要地宽容。 DR#599的解决方案收紧了要求,也禁止了void *
。