Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are ifs tested in the order they have been written is a if-else...if-else...if-else block?

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();
    }
}
like image 267
Mesop Avatar asked May 09 '12 18:05

Mesop


Video Answer


2 Answers

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.

like image 153
Ed S. Avatar answered Nov 15 '22 07:11

Ed S.


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.

like image 41
outis Avatar answered Nov 15 '22 06:11

outis