【问题标题】:Is a statement void(); legal and what is it actually?是一个声明 void();合法的,实际上是什么?
【发布时间】:2017-03-29 14:33:52
【问题描述】:

我有一小段代码,其中有一个声明 void();

int main() 
{
   void( ); // 1: parses fine in GCC 5.4.0 -Wpedantic 
   // void;    // 2: error declaration does not declare anything
} 

1 void() 到底是什么?

  • 匿名函数声明?
  • 类型声明?
  • 空表达式?

是什么让 1 void() 与 2 void; 不同?

我已经读过了:

  1. Is sizeof(void()) a legal expression? 但 void() 被认为是 sizeof 中的一种类型
  2. What does the void() in decltype(void()) mean exactly? 在 declspec 中考虑。
  3. 我读到了Is void{} legal or not?

但我很好奇松散的声明 void();不同于其中之一(当然是为什么)

【问题讨论】:

  • 我怀疑 void() 类似于例如int pi = int(3.14); ...除了将 3.14 转换为 int 之外,您将空表达式转换为 void 类型(然后忽略结果,因为它是 void 类型,所以无论如何您都必须这样做)。
  • 相关:stackoverflow.com/questions/39279074/… 我正在努力寻找更好的骗子
  • 可能在模板中很有用,这样您就不必专门研究 void?
  • 对于那些将我指向可能的骗子的人:大多数相关问题都是由用户 skypjack 提出的,类似于我在问题中提出的问题。但是我还没有看到“松散声明” void(); 的情况。被考虑,但仅在 decltype、sizeof 等的上下文中。

标签: c++ language-lawyer


【解决方案1】:

void; 是一个错误,因为语言语法中没有与该代码匹配的规则。特别是没有规则type-id;

但是,代码void() 匹配两个语法规则:

  1. type-id .
  2. postfix-expression,子案例为 simple-type-specifier ( expression-list-opt )

现在,解析器需要将void(); 与语法规则相匹配。尽管 void() 匹配 type-id,但如前所述,没有规则可以匹配 type-id ;。所以解析器拒绝void()在这种情况下可能解析为type-id,并尝试另一种可能性。

一系列规则定义postfix-expression; 作出声明。所以void() 在这种情况下被明确地解析为 postfix-expression

正如您已经链接的其他答案所述,此代码作为 后缀表达式 的语义含义是 void 类型的纯右值。

相关链接:Is sizeof(int()) a legal expression?

【讨论】:

  • 我认为 [stmt.ambig] 是这里更接近的消歧规则。当然,首先没有歧义。
  • @T.C.我已经编辑了,希望现在更准确。我不是解析专家,请随意整理任何东西
  • 准确地说:这个后缀表达式是显式转换?根据“en.cppreference.com/w/cpp/language/explicit_cast”,第四个实际上对 void 有具体解释:如果 new_type 是(可能是 cv 限定的)void,则表达式是一个没有结果对象的 void prvalue(C++17 起)。 标准中找不到对应的语句
  • @Andre “结果对象”是 C++17 中的新内容,N4618 中的 [basic.lval]/2 包含您的 cppreference 引用所基于的文本。
【解决方案2】:

void 表达式。

编译器不会为它创建任何代码,例如,

在VS中

_asm
{
    nop;
}
void();
_asm
{
    nop;
}

产生这个程序集:

_asm
{
    nop;
003017CE  nop  
}
void();
_asm
{
    nop;
003017CF  nop  
}

【讨论】:

    猜你喜欢
    • 2013-07-09
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 2021-05-12
    • 2011-08-01
    • 2011-12-26
    • 1970-01-01
    相关资源
    最近更新 更多