Are ifs tested in the order they have been written is a if-else...if-else...if-else block?
c++, if-statement
Solution
From C++03, § 6.4 Selection Statements:
1
selection-statement:
if ( condition ) statement
if ( condition ) statement else statement
switch ( condition ) statement
[...] If the substatement in a selection-statement is a single statement and not a compound-statement, it is as if it was rewritten to be a compound-statement containing the original substatement. [Example:
if (x)
int i;
can be equivalently rewritten as
if (x) {
int i;
}
[...]
6.4.1 The `if` statement
1 If the condition (6.4) yields `true` the first substatement is executed. If the `else` part of the selection statement is present and the condition yields `false`, the second substatement is executed. [...]
From 6.4 1, your sample code is equivalent to:
if (cond1) {
doSomething1();
} else {
if (cond2) {
doSomething2();
} else {
if (cond3) {
doSomething3();
} else {
doElse();
}
}
}
Note this doesn't mean the code is transformed to the above, but rather that the two must behave the same.
From 6.4.1, an inner `if` statement is executed when the condition for the outer `if` is `false`. If the condition is `true`, the first branch is executed. While the standard doesn't explicitly state the second branch isn't executed when the condition is `true`, it's strongly implied by omission.
According to § 1.9 1:
The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine. This International Standard places no requirement on the structure of conforming implementations. In particular, they need not copy or emulate the structure of the abstract machine. Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.5)
5) This provision is sometimes called the “as-if” rule, because an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program. For instance, an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced.
So part of the `else` substatement may be executed if it's side-effect free and the results discarded even if the condition turns out to be `true`. A substatement condition, for example, may be partially executed within the processor pipeline if branch prediction incorrectly predicts that the condition will be `false`. However, the affects of this must not be noticeable, so (from your perspective) it's as if the substatements behave as outlined by §s 6.4 1 and 6.4.1 1.
Problem
Is there any guarantee, that the ifs of a `if-else if-else if-else` block, are tested in the order in which they have been written. I am asking that because I am often trying to optimizing my code by putting the most frequent cases firsts and I want to know if some optimisations done by the compiler could change the order in which the if are tested. So, if I am writting a code like that: ``` if (cond1) // First if (for the case I have the most often) { doSomething1(); } else if (cond2) // Second if (for the second case I have the most often) { doSomething2(); } else if (cond3) // Third if (for the third case I have the most often) { doSomething3(); } else { doElse(); } ``` Is there any guarantee that after being compiled (for release), the first if will be tested, then the second if, then the third if (and finally the else is executed if none of the condition was true). I know that when debugging, the ifs are executed in the order I wrote them, but will it stays true when the program is compiled for release (I am mostly using recent version of g++ and visual studio). Also, since, the condition can have effect on the environnement (like `if (i=a)` or `if(myfunction())`), they should be executed as written, but I wonder if I am missing some optimisation that the compiler could do, that would change the order in which the ifs are tested. Especially, if the condition don't have side effects like that: ``` void test(int a) { if (a == 1) { doSomething1(); } else if (a == 2) { doSomething1(); } else if (a == 3) { doSomething1(); } else { doSomething1(); } } ```