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
"if" block without curly braces makes subsequent "else if" nested
提问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_1
is considered inside the if
block.
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 if
is automatically nested inside the outerif
block. g++ -Wall
issues 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].
回答by Konrad Rudolph
The behaviour isn't actually different, it's entirely consistent: the whole inner if
block – including else if
–?is considered as oneblock.
行为实际上并没有什么不同,它是完全一致的:整个内部if
块——包括else if
–? 被视为一个块。
This is a classical ambiguity in parsing, known as the “dangling-else
problem”: there are two valid ways of parsing this when the grammar is written down in the normal BNF:
这是解析中的一个经典歧义,被称为“悬空else
问题”:当语法写在正常的 BNF 中时,有两种有效的解析方法:
Either the trailing else
is 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 else
is 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
else
statement always attaches to nearest if
. Without branches nested if
itself does not form meaningful statement, so parser goes on.
else
声明总是附加到最近的if
。没有分支嵌套if
本身不会形成有意义的语句,因此解析器继续。