Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convincing a colleague about their if not being nested

One of my university colleagues, who has started programming this year, sometimes writes if statements like this:

if(something) doA();
else
    if(something2) doC();
    else doD();

He is conviced that the second if-else pair is treated as a single entity, and that it is in fact nested under the first else.

I'm, however, sure that his code is equivalent to:

if(something) doA();
else if(something2) doC();
else doD();

This shows that the second else is not actually nested, but on the same level as the first if. I told him he needs to use curly braces to achieve what he wants to.

"But my code works as intended!"

And indeed, it worked as intended. Turns out the behavior of the code was the same, even if the else was not nested.

Surprisingly, I have found myself unable to write a clear and concise example that shows different behavior between

if(something) doA();
else
    if(something2) doC();
    else doD();

and

if(something) doA();
else {
    if(something2) doC();
    else doD();
}

Can you help me find an example that will show my colleague the difference between using/not using curly braces?

Or is the incorrect-looking version always equivalent to the one with curly braces, in terms of behavior?

like image 529
Vittorio Romeo Avatar asked Jan 13 '14 16:01

Vittorio Romeo


2 Answers

Per C 2011 6.8.4 1, the grammar for a selection-statement includes this production:

selection-statement: if ( expression ) statement else statement

Per 6.8 1, a production for statement is:

statement: selection-statement

Thus, in:

if(something) doA();
else
    if(something2) doC();
    else doD();

the indented if and else form a selection-statement that is the statement that appears in the else clause of the preceding selection-statement.

The productions I have shown show that this is a possible interpretation in the C grammar. To see that it is the only interpretation, we observe that the text in the else clause of the initial selection-statement must be a statement, because there is no other production in the C grammar that produces an else keyword. (This is most easily seen by searching the grammar in clause A.2. Due to its size, I will not reproduce it here.) So we know the else is followed by a statement. We can easily see that the statement is a selection-statement, since it begins with if. Then the only question remaining is whether the next else is part of that if statement or not. Per 6.8.4.1 3, “An else is associated with the lexically nearest preceding if that is allowed by the syntax.”

like image 64
Eric Postpischil Avatar answered Nov 20 '22 09:11

Eric Postpischil


Both structures come out to the same thing. The compiler effectively sees the code as:

if ( something ) {
    doA()
} else {
    if ( something2 ) {
        doC();
    } else {
        doD();
    }
}

In practice, however, there is no different between this and:

if ( something ) {
    doA();
} else if ( something2 ) {
    doC();
} else {
    doD();
}

The extra braces encapsulate a single statement, and you don't actually need the braces when the if or the else controls a single statement. (My first example puts every statement except the encompassing if in braces.)

Logically, programmers tend to thing along the lines of the second; languages where some sort of bracing ({}, BEGIN/END or indentation) is required almost always add an elsif or elif keyword in order to permit this second form. C and C++ (and Java, and C#, and...) don't, because the second form works out without the extra keyword.

In the end, you don't want the extra indentation. (I've cases with fifteen or twenty successive else if. That would make for some serious indentation.) On the other hand, you do want the controlled statement on a separate line. (Bracing is optional: if your coding standard puts the brace on a separate line, it's also conventional to suppress it if it only contains a single statement.)

like image 24
James Kanze Avatar answered Nov 20 '22 10:11

James Kanze