C++ 没有花括号的“if”块使后续的“else if”嵌套

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11734604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:29:02  来源:igfitidea点击:

"if" block without curly braces makes subsequent "else if" nested

c++cif-statementnested-if

提问by iammilind

AFAIK, if an "if" block is not provided the curly braces then only 1 statement is considered inside it. e.g.

AFAIK,如果没有为“if”块提供大括号,则在其中只考虑 1 条语句。例如

if(..)
  statement_1;
  statement_2;

Irrespective of tabs, only statement_1is considered inside the ifblock.

statement_1不考虑选项卡,只考虑在if块内。

Following code doesn't get along with that:

以下代码与此不符:

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

Above code doesn't print anything. It should have printed "true".
It appears as of the else ifis automatically nested inside the outerifblock. g++ -Wallissues warning, but that is not the question here. Once you put the curly braces, everything goes fine as expected.

上面的代码不打印任何东西。它应该打印"true".
它显示为else if自动嵌套在外部if块内。g++ -Wall发出警告,但这不是这里的问题。一旦你放上花括号,一切都会按预期进行。

Why such different behavior ?
[GCC demo: without bracesand with braces].

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

回答by Konrad Rudolph

The behaviour isn't actually different, it's entirely consistent: the whole inner ifblock – including else if–?is considered as oneblock.

行为实际上并没有什么不同,它是完全一致的:整个内部if块——包括else if–? 被视为一个块。

This is a classical ambiguity in parsing, known as the “dangling-elseproblem”: there are two valid ways of parsing this when the grammar is written down in the normal BNF:

这是解析中的一个经典歧义,被称为“悬空else问题”:当语法写在正常的 BNF 中时,有两种有效的解析方法:

Either the trailing elseis part of the outer block, or of the inner block.

尾部要么else是外部块的一部分,要么是内部块的一部分。

Most languages resolve the ambiguity by (arbitrarily) deciding that blocks are matched greedily by the parser – i.e. the else[if] is assigned to the closest if.

大多数语言通过(任意地)决定解析器贪婪地匹配块来解决歧义 - 即else[ if] 被分配给最接近的if

回答by BenW

Because the elseis actually being grouped with the innerif, not the outer one. It's actually being parsed as

因为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";
    }
  }
}

You can solve the problem by explicitly putting the braces where you want them.

您可以通过明确地将大括号放在您想要的位置来解决问题。

回答by Michael Chinen

It shouldn't print anything. It is the equivalent to this, since the second if/else if is one block that belongs to the first if:

它不应该打印任何东西。它与此等效,因为第二个 if/else if 是属于第一个 if 的块:

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

回答by user396672

It is quite natural from the C parser viepoint.

从 C 解析器的角度来看,这是很自然的。

The parser, while parsing if-statement, parses the condition expression first, then parses the first statement after condition, then looks for elsekeyword and, if the elsepresents, parses the second (alternative) statement.

解析器在解析 if 语句时,首先解析条件表达式,然后解析条件之后的第一个语句,然后查找else关键字,如果else出现,则解析第二个(替代)语句。

However, the first statement is an if-statement too, so the parser calls the "if-parser" recursively (before testing for elsekeyword!). This recursive call parses the inner if-else statement completely (including else), and moves token position "past the end" of the whole code fragment.

然而,第一个语句也是一个 if 语句,所以解析器递归地调用“if-parser”(在测试else关键字之前!)。这个递归调用完全解析内部 if-else 语句(包括else),并将标记位置移动到整个代码片段的“末尾”。

Any attempt to implement alternative behaviour should involve some additional communication between "outer" and "inner" if-parsers: the outer parser should inform the "inner" not to be greedy(i.e. not to eat the elsestatement). This would add additional complexity to the language syntax.

任何实现替代行为的尝试都应该涉及“外部”和“内部”if 解析器之间的一些额外通信:外部解析器应该通知“内部”不要贪婪(即不要吃else语句)。这会增加语言语法的复杂性。

回答by Roman Saveljev

elsestatement always attaches to nearest if. Without branches nested ifitself does not form meaningful statement, so parser goes on.

else声明总是附加到最近的if。没有分支嵌套if本身不会形成有意义的语句,因此解析器继续。