阅读了最令人烦恼的解析后,我进行了一些实验并找到了这个程序。有两条非常相似的线。其中一个在g ++ 7和clang ++ - 3.9中产生警告,另一个则没有。
articles[5:][:50]
在第二行中,创建了int main() {
void(); // no warning
int(); // warning: statement has no effect
}
类型的默认构造对象并立即销毁,因此未使用。但是第一行会发生什么?如果以相同的方式解析它,则应该是错误,因为创建类型为int
的对象是非法的。另一方面,它看起来也不像函数声明。
答案 0 :(得分:5)
解析没有区别。这两种情况都包含在 simple-type-specifier 中,后跟可选的带括号的表达式列表。
语义是在C ++ 17(N4659)[expr.type.conv] / 2中指定的:
如果类型为 cv
void
且初始值设定项为()
,则表达式是指定类型的prvalue,不执行初始化。否则,表达式是指定类型的prvalue,其结果对象使用初始化程序进行直接初始化。
这明确指出void()
是void
类型的prvalue。
现在,我确定它不是意图,类型为void的prvalue是非法的,因为它是常见的,例如, (void)x;
或调用void函数!
但是我无法在标准中找到适用于void
prvalues的临时实现的内容。 [class.temporary] / 2似乎说丢弃值表达式总是实现临时的;并且实现不完整类型的prvalue是错误的。也许这是标准中的缺陷。
关于"未使用值"的警告差异可能是因为void
类型的未使用值是常见的,并且警告它没有帮助。
答案 1 :(得分:0)
以相同的方式解析 。
警告不是来自解析器。它们在语义分析期间出现。 SA注意到创建的值被int();
销毁而没有被读取或写入。
在void
案例中,没有任何价值,因此没有警告。