“如果”没有花括号块使随后的“否则,如果”嵌套(“if” block without curly b

2019-06-26 15:14发布

据我所知,如果一个“如果”块不提供大括号则只有1陈述,认为里面。 例如

if(..)
  statement_1;
  statement_2;

不论标签,只有statement_1被认为是内部的if块。

下面的代码不会与相处:

int main ()
{
  if(false)  // outer - if
    if(false)  // nested - if
      cout << "false false\n";
  else if(true)
    cout << "true\n";
}

上面的代码不显示任何信息。 它应该印有"true"
它显示为的else if自动嵌套在外部if块。 g++ -Wall发出警告,但在这里不是问题。 一旦你把大括号,按预期一切顺利。

为什么会有如此不同的行为?
[GCC演示: 无括号和用大括号 。

Answer 1:

该行为是不是实际上是不同的,这是完全一致的:整个内if块-包括else if -被认为是一个块。

这是在分析经典模糊性,被称为“dangling- else问题” :有些时候语法在正常BNF减记解析这两种有效方法:

任一尾随else为外块,或内块的一部分。

大多数语言解析由(任意)决定该块解析器贪婪地匹配的模糊性-即else [ if ]被分配到最接近if



Answer 2:

因为else实际上是被与分组if ,不是外部的。 它实际上是被解析为

int main ()
{
  if(false)  // outer - if (never gets executed)
  { 
    if(false)  // nested - if
    {
        cout << "false false\n";
    } else if(true) {
        cout << "true\n";
    }
  }
}

你可以明确地把你想让他们的括号解决问题。



Answer 3:

它不应该打印出任何东西。 如果/否则,如果是属于第一,如果一个块是等同于此,由于第二:

  if(false) {
    if(false)  // nested - if
      cout << "false false\n";
    else if(true)
      cout << "true\n";
  } 


Answer 4:

这是从C解析器viepoint很自然的。

解析器,在解析if语句,解析条件表达式,然后再解析条件后的第一个语句,然后寻找其他关键字,如果别的礼物,解析第二(替代)语句。

然而,第一条语句是一个if语句,所以解析器调用“如果解析器”递归(用于测试其他关键字之前!)。 这个递归调用解析内if-else语句完全(包括 ),并且移动标记位置“过去的结束”整个代码片段。

实施替代行为的任何企图应包括“外”与“内”如果的解析器之间的一些额外的通信:外解析器应该告知“内部”不贪(即不要吃else语句)。 这将增加额外的复杂语言的语法。



Answer 5:

else语句总是连接到最近的if 。 如果没有嵌套分支if本身不构成有意义的语句,所以解析器继续。



文章来源: “if” block without curly braces makes subsequent “else if” nested