解析 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
类型的值很常见,因此发出警告没有帮助。
阅读了最令人烦恼的解析后,我做了一些实验并找到了这个程序。有两条非常相似的线。其中一个在 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
类型的值很常见,因此发出警告没有帮助。