There's no ambiguity; let's look up the actual grammar (C++11 §A.5):
The while
and for
are under iteration-statement
iteration-statement:
while (
condition)
statement
do
statement while (
expression)
for (
for-init-statement conditionopt;
expressionopt)
statement
(each row is an alternative pattern that satisfies the term that precedes the colon in the first row; words in italic are references to other grammar rules; the opt marks optional terms)
if
and if
/else
are under selection-statement:
selection-statement:
if (
condition )
statement
if (
condition )
statement else
statement
switch (
condition )
statement
Now, as you can see they all require one, single, generic "statement" to execute, with no explicit mention of the braces; statement, in turn, is defined as:
statement:
labeled-statement
attribute-specifier-seqopt
expression-statement
attribute-specifier-seqopt
compound-statement
attribute-specifier-seqopt
selection-statement
attribute-specifier-seqopt
iteration-statement
attribute-specifier-seqopt
jump-statement
declaration-statement attribute-specifier-seqopt
try-block
let's forget about attribute-specifier-seqopt; the point to take home is that a statement in turn can be any of the while
/for
/if
above, plus some other stuff, including the compound-statement, i.e. the braces:
compound-statement:
{
statement-seqopt }
statement-seq:
statement
statement-seq statement
(which is a formal way to say that inside the braces you can put one or more statements)
Now, with this knowledge we can disentangle your example by thinking mechanically like the parser does:
for (condition)
if (condition)
doA();
else
doB();
if (condition)
doC();
else
doD();
the for
after the stuff in the ()
wants a statement; let's try to parse what follows as such:
there's an if
; if
either wants just a statement of a statement followed by else
and another statement; let's see:
doA()
is an expression-statement
- an
else
follows
doB()
is an expression-statement
thus the whole if (condition) doA(); else doB();
is a statement, in particular a selection-statement
ok, we have full statement to provide as loop body to the for
, so the for
statement is completed;
then, we have an if-else
, which is parsed as above
doC()
is an expression-statement
- an
else
follows
doD()
is an expression-statement
Thus, the final "braced" interpretation is
for (condition) {
if (condition) {
doA();
} else {
doB();
}
}
if (condition) {
doC();
} else {
doD();
}