【问题标题】:Difference between parsing of void() and int()void() 和 int() 解析的区别
【发布时间】:2018-08-01 10:52:34
【问题描述】:

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

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

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

【问题讨论】:

标签: c++ language-lawyer most-vexing-parse


【解决方案1】:

解析没有区别。这两种情况都由 simple-type-specifier 覆盖,后跟可选的带括号的 expression-list

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

如果类型是 cv void 并且初始化程序是 () ,则表达式是不执行初始化的指定类型的纯右值。否则,表达式是指定类型的纯右值,其结果对象使用初始化程序直接初始化。

这特别说明void()void 类型的纯右值。

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

但我找不到标准中的哪个位置说应该为void prvalues 禁止临时实现。 [class.temporary]/2 似乎是说丢弃值表达式总是物化一个临时值;实现不完整类型的prvalue是错误的。也许是标准的缺陷。


关于“未使用值”的警告差异可能是因为void 类型的未使用值是常见的,并且警告不会有帮助。

【讨论】:

    【解决方案2】:

    以同样的方式解析的。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      • 2016-07-24
      • 2018-03-16
      • 1970-01-01
      相关资源
      最近更新 更多