开发者

C++ Optimizing If Statements

开发者 https://www.devze.com 2023-03-22 05:52 出处:网络
Consider following statement: C a, b; //C contains c1, c2 and c3 all integers if(a.c1==b.c1 && a.c2 == b.c2) {

Consider following statement:

 C a, b; //C contains c1, c2 and c3 all integers

if(a.c1==b.c1 && a.c2 == b.c2) {
     a.c3=b.c3;
 }

Will this statement be optimized to the following:

 if(a.c1 == b.c1) {
    if(a.c2 == b.c2) {
       a.c3=b.c3;
    }
 }

AFAIK, C++ compilers does not perform this kind of operation since it can have side effects. But these are built-in types.

  • Is there anything related in the standard?
  • If it is compiler specific is main stream compilers (MS, GNU开发者_StackOverflow中文版, Intel) are doing it or not?


Yes. The following code snippet:

C a, b; //C contains c1, c2 and c3 all integers
if(a.c1==b.c1 && a.c2 == b.c2)
{
    a.c3=b.c3;
}

will be "optimized" to this (or something equivalent):

if(a.c1 == b.c1)
{
    if(a.c2 == b.c2)
    {
        a.c3=b.c3
    }
}

This is required not because of optimization but because the C++ standard requires short-circuit evaluation. So reasonably standards-conforming C++ compilers should be able to short-circuit that.

There isn't a single place in the C++ standard that explicitly states that some boolean operators are short-circuited. It is implied from the rules:

ISO/IEC C++ Standard 14882 §5.14 Logical AND operator [expr.log.and]

logical-and-expression:
    inclusive-or-expression
    logical-and-expression && inclusive-or-expression
  1. The && operator groups left-to-right. The operands are both implicitly converted to type bool (clause 4). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.

The rules are similar for the || operator:

ISO/IEC C++ Standard 14882 §5.15 Logical OR operator [expr.log.or]

logical-or-expression:
    logical-and-expression
    logical-or-expression || logical-and-expression
  1. The || operator groups left-to-right. The operands are both implicitly converted to bool (clause 4). It returns true if either of its operands is true, and false otherwise. Unlike |, || guarantees left-to-right evaluation; moreover, the second operand is not evaluated if the first operand evaluates to true.

And the conditional ? operator:

ISO/IEC C++ Standard 14882 §5.16 Conditional operator [expr.cond] conditional-expression: logical-or-expression logical-or-expression ? expression : assignment-expression

  1. Conditional expressions group right-to-left. The first expression is implicitly converted to bool (clause 4). It is evaluated and if it is true, the result of the conditional expression is the value of the second expression, otherwise that of the third expression. All side effects of the first expression except for destruction of temporaries (12.2) happen before the second or third expression is evaluated. Only one of the second and third expressions is evaluated.


Standard 5.14 / 1 :

The && operator groups left-to-right. The operands are both implicitly converted to type bool (clause 4). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.


C++ uses shirt-circuit evaluation. So, in a way it will work that way.

I doesn't actually evaluate and optimize the code that way, but it will evaluate to the equivalent in assembly code.


The && operator is short-circuiting. In other words, if a.c1 == b.c1 fails to evaluate to true, then a.c2 == b.c2 won't even be evaluated.

It is similar to the solution you describe, but it is part of the C++ language (and seems much easier to read than explicitly typing nested if statements).

0

精彩评论

暂无评论...
验证码 换一张
取 消