Reputation: 5263
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();
}
}
Upvotes: 6
Views: 1266
Reputation: 77440
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
statement1 If the condition (6.4) yields
true
the first substatement is executed. If theelse
part of the selection statement is present and the condition yieldsfalse
, 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.
Upvotes: 6
Reputation: 154007
No. The only thing that is guaranteed is that the observable behavior be "as if" the ifs were evaluated in order. The evaluation of the conditions may even be interleaved, with part of cond2 preceding cond1, and another part after cond1 has been evaluated. On the other hand, the guarantee that the results will be "as if" the ifs had been evaluated in order, if some of the conditions have side effects, those side effects won't occur if one of the earlier ifs was true.
With regards to optimization, by all means put the most likely conditions first. In practice, the compiler will only move code if it knows that the movement will improve things, so if the conditions are more or less independent, and the compiler cannot "optimize" them by folding parts of them, then the order will be preserved. Unless the compiler is exceptionally good, and can determine that your ordering wasn't optimal (on the basis of profiler output).
Upvotes: 5
Reputation: 40887
C++ compilers are only allowed, with a few exceptions, to optimize statements to something so long as that something else behaves "as-if" it were performing the non-optimized statements.
Reordering the statements of an if/else tower would not behave "as-if" it had not been reordered (unless of course the compiler can prove that it would be, like when some checks are always true or false and have no side effects).
You absolutely can depend on the ordering of your if/else tower.
Upvotes: 0
Reputation: 124752
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).
Yes, but not specifically for if statements, for all of your (single threaded) code.
C++ code is executed top down, from the beginning to the end. The only time this may not be the case is when you make asynchronous calls or have multiple threads calling the same code simultaneously.
Upvotes: 7
Reputation:
yes, the conditions are checked in the order of the if, else if, else structure. Within a given conditional check, things can be tweaked a bit with parentheses.
Upvotes: 0