为什么删除 void* 是 UB 而不是编译错误?

Why deleting void* is UB rather than compilation error?

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

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

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

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

为什么不只是格式错误的语法无效的程序?看起来 Standard 并没有花太多时间在上面,在 [expr.delete] 中说

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

为什么我会遗漏这不会触发硬编译错误的原因?

在现代 C++ 中,删除 void * 指针 错误格式(即我们通常称之为 "compilation error")

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

void * 不是指向对象类型的指针。

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

规范中的这一更改似乎是由 defect report #599 触发的。原始规范允许在 delete-expression 中提供 any 指针类型的空指针,例如函数指针。这看起来过于宽容了。 DR#599 的决议收紧了要求,同时取缔了 void *