C++ void()和int()解析之间的差异
在阅读了最烦人的解析之后,我做了一些实验,发现了这个程序。有两条非常相似的线。其中一个在g++7和clang++-3.9中都会产生警告,另一个则不会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的对象是非法的。另一方面,
int main() {
void(); // no warning
int(); // warning: statement has no effect
}
在第二行中,创建并立即销毁了类型为int
的默认构造对象,因此未使用。但是第一行发生了什么?如果以相同的方式对其进行分析,则应为错误,因为创建类型为void
的对象是非法的。另一方面,它看起来也不像一个函数声明。它的解析方式相同
警告不是来自解析器。它们出现在语义分析过程中。SA注意到一个值是由int()创建的代码>未被读取或写入
在void
情况下,没有值,因此没有警告。解析没有区别。这两种情况都由简单类型说明符和可选的括号表达式列表所涵盖
语义在C++17(N4659)[expr.type.conv]/2中指定:
如果类型为cvvoid
且初始值设定项为()
,则表达式是指定类型的prvalue,不执行初始化。否则,表达式是指定类型的prvalue,其结果对象由初始值设定项直接初始化
这特别说明void()
是void
类型的prvalue
现在,我确信void类型的prvalue不是非法的,因为这是一种常见的情况,例如(void)x代码>或调用void函数
但是我在标准中找不到什么地方说,对于void
prvalue,应该抑制临时物化。[class.temporary]/2似乎说一个被丢弃的值表达式总是具体化一个临时值;将不完整类型的prvalue具体化是一个错误。也许这是标准中的一个缺陷
关于“未使用值”的警告的区别可能是因为类型为void
的未使用值是一种常见情况,对其进行警告没有帮助 嗯,可能与此有关吗?->->@Raindrop7 Try-Wall-Wextra,我的结果与之一致。强制转换到void
用于删除有关未使用变量的警告。他们可能会以同样的方式对待这个表达式。@Jarod42它是一个显式类型转换,所以我不知道为什么人们会把它看作是强制转换。