C++ void()和int()解析之间的差异

C++ void()和int()解析之间的差异,c++,language-lawyer,most-vexing-parse,C++,Language Lawyer,Most Vexing Parse,在阅读了最烦人的解析之后,我做了一些实验,发现了这个程序。有两条非常相似的线。其中一个在g++7和clang++-3.9中都会产生警告,另一个则不会 int main() { void(); // no warning int(); // warning: statement has no effect } 在第二行中,创建并立即销毁了类型为int的默认构造对象,因此未使用。但是第一行发生了什么?如果以相同的方式对其进行分析,则应为错误,因为创建类型为void的对象是非法的。另一方面,

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

int main() {
  void(); // no warning
  int(); // warning: statement has no effect
}
在第二行中,创建并立即销毁了类型为
int
的默认构造对象,因此未使用。但是第一行发生了什么?如果以相同的方式对其进行分析,则应为错误,因为创建类型为
void
的对象是非法的。另一方面,它看起来也不像一个函数声明。

它的解析方式相同

警告不是来自解析器。它们出现在语义分析过程中。SA注意到一个值是由
int()创建的未被读取或写入


void
情况下,没有值,因此没有警告。

解析没有区别。这两种情况都由简单类型说明符和可选的括号表达式列表所涵盖

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

如果类型为cv
void
且初始值设定项为
()
,则表达式是指定类型的prvalue,不执行初始化。否则,表达式是指定类型的prvalue,其结果对象由初始值设定项直接初始化

这特别说明
void()
void
类型的prvalue

现在,我确信void类型的prvalue不是非法的,因为这是一种常见的情况,例如
(void)x或调用void函数

但是我在标准中找不到什么地方说,对于
void
prvalue,应该抑制临时物化。[class.temporary]/2似乎说一个被丢弃的值表达式总是具体化一个临时值;将不完整类型的prvalue具体化是一个错误。也许这是标准中的一个缺陷



关于“未使用值”的警告的区别可能是因为类型为
void
的未使用值是一种常见情况,对其进行警告没有帮助

嗯,可能与此有关吗?->->@Raindrop7 Try-Wall-Wextra,我的结果与之一致。强制转换到
void
用于删除有关未使用变量的警告。他们可能会以同样的方式对待这个表达式。@Jarod42它是一个显式类型转换,所以我不知道为什么人们会把它看作是强制转换。