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?
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.”
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.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With