解析 void() 和 int() 的区别

Difference between parsing of void() and int()

阅读了最令人烦恼的解析后,我做了一些实验并找到了这个程序。有两条非常相似的线。其中一个在 g++7 和 clang++-3.9 中都会产生警告,另一个则不会。

int main() {
  void(); // no warning
  int(); // warning: statement has no effect
}

在第二行中,创建了一个 int 类型的默认构造对象并立即销毁,因此未使用。但是第一行发生了什么?如果按照同样的方式解析,应该是错误的,因为创建void类型的对象是非法的。另一方面,它看起来也不像函数声明。

以相同的方式解析。

警告不是来自解析器。它们出现在语义分析期间。 SA 注意到一个值被 int(); 创建和销毁,而没有被读取或写入。

void的情况下,没有值,所以没有警告。

解析没有区别。这两种情况都包含在 simple-type-specifier 后面,后面是可选的括号 expression-list.

语义在C++17 (N4659)中指定 [expr.type.conv]/2:

If the type is cv void and the initializer is () , the expression is a prvalue of the specified type that performs no initialization. Otherwise, the expression is a prvalue of the specified type whose result object is direct-initialized with the initializer.

这明确表示 void() 是类型 void 的纯右值。

现在,我确定有意 void 类型的纯右值是非法的,因为它很常见,例如(void)x; 或调用 void 函数!

但我找不到标准中的哪个地方说应该为 void 个纯右值抑制临时物化。 [class.temporary]/2 似乎在说 discarded-value 表达式总是具体化一个临时的;实现不完整类型的纯右值是错误的。也许这是标准的缺陷。


有关 "unused value" 的警告的不同之处可能是因为未使用的 void 类型的值很常见,因此发出警告没有帮助。