0

I was curious about what would be default nesting in the body of a for loop and while loop in cases with no brackets.

I.E.

while (condition) //without brackets
if (condition)
else

and

for (condition) 
if (condition)
else

versus

while (condition)
for (condition)
if (condition
else

I know that for loop will nest an else if there is an if within it's body whenever there is no bracket presented. What happens with a while loop? Would it be the same? And also, including a while and a for loop within the condition? Would it turn out something like

while (condition) {
   for (condition) {
       if (condition)
       else
   } // for
} //while

What happens if there was another set of if and else in the for loop? Would it just be ignored into

for (condition)
    if (condition)
    else 
if (condition)
else

Is there any other case I should watch for?

Bao Thai
  • 533
  • 1
  • 6
  • 25
  • 1
    This should help http://stackoverflow.com/questions/2125066/is-it-bad-practice-to-use-an-if-statement-without-brackets – compilererror Feb 21 '16 at 21:26
  • Free advice: Don't tempt the devil... `else` is must be preceded by an `if` and together, they form a control block... a control block under a while/for loop is permitted – WhiZTiM Feb 21 '16 at 21:26
  • I understand there is a certain style, I am just curious where does a default for loop and while loop go up to instead of just reading that one single line when there are no brackets – Bao Thai Feb 21 '16 at 21:29

6 Answers6

4

while (condition) applies to the next statement. Often we use a compound statement, i.e., a line or more of code enclosed in curly braces:

while (condition)
{
/* code goes here */
}

but the statement doesn't have to be a compound statement:

while (condition)
    std::cout << "I'm still in the condition.\n";

and sometimes the statement can be more complicated:

while (condition)
    if (some_other_condition)
        /* some code here */
    else
       /* some other code here */

and the statement can be a looping statement:

while (condition)
    while (another_condition)
        while (yet_another_condition)
            /* whew, we got here! */
Pete Becker
  • 74,985
  • 8
  • 76
  • 165
3

The point is that all loops might iterate over a control block, which might either be:

  1. a single control block (e.g. a statement), or
  2. multiple control blocks grouped to a single one by {...}.

In your case,

while (condition)
for (condition)
if (condition)
else

if...else form a single control block, and so does for; hence, this is unambigously identical to

while (condition) {
    for (condition) {
        if (condition) {
           ...
        } else {
           ...
        }
    }
}
Marcus Müller
  • 34,677
  • 4
  • 53
  • 94
1

In all your examples, there is not a even a subtle point of confusion. There's only one way to interpret any of these so that it can compile. Try it yourself: place curly braces ('{' & '}') in each code fragment and try to give it 2 different meanings. You won't be able to do that.

Amit
  • 45,440
  • 9
  • 78
  • 110
0

There are no specific nesting rules for loops and conditional expressions. You just have to keep in mind that if you don't use braces, the loop executes only one statement.

Generally it is a good idea to always use braces.

Frank Puffer
  • 8,135
  • 2
  • 20
  • 45
0

The both iteration statements are defined like

while ( condition ) statement
                    ^^^^^^^^^
for ( for-init-statement conditionopt; expressionopt) statement
                                                      ^^^^^^^^^ 

where statement is any statement including the compound statement or empty statement.

So for example in this construction

while (condition) //without brackets
if (condition) statement
else statement

the statement is the if-else statement

if (condition) statement
else statement

You could enclose it in braces making a compound statement containing a single if-else statement

while (condition) //without brackets
{
if (condition) statement
else statement
}

However the effect would be the same.

In this construction

while (condition)
for (condition)
if (condition) statement
else statement

the while loop has the for loop as its statement that in turn has if-else as its own statement. You could write for example

while (condition)
{
    for (condition)
    {
        if (condition) statement
        else statement
    }
}

however the both compound statements contain only a single statement. So these two constructions are equivalent.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

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();
}
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299