C ++ Compiler Optimization and Short Circuit Evaluation

Here is my code:

b = f() || b; 

The f() function has a side effect and should always be executed. As a rule, only the right operand can be shorted, and this code should work. But I am afraid that some compilers reverse two operands, as they are more effective for short-circuiting function evaluations, and not for simple evaluating variables. I know that g ++ -O3 can break some specs, but I don't know if this code can affect.

So is my code risk free?

I knew Are coded logical operators short laws? And the evaluation procedure? , but my question was about optimizing compilers, I didn’t know that they could not violate standards (even if it would be strange).

+6
source share
2 answers

But I'm afraid some compilers will reverse two operands

These expressions must be evaluated from left to right. This is described in the standard about operators && , || , ? and,. They specifically mention order as well as forced sequence points.

§5.14.1 (logical AND)

The operators of the && group from left to right. The operands are converted to context in bool (section 4). The result is true if both operands are true and false otherwise. Unlike & , && guarantees an evaluation from left to right : the second operand is not evaluated if the first operand is false.

§5.15.1 (logical OR)

Group Operators || from left to right. The operands are converted to context in bool (section 4). It returns true if any of its operands is true, and false otherwise. Unlike | , || guarantees an assessment from left to right ; in addition, the second operand is not evaluated if the first operand is true.

§5.16.1 (conditional statement)

Group conditional expressions from right to left. The first expression is contextually converted to bool (section 4). It is evaluated and, if true, the result of the conditional expression is the value of the second expression, otherwise the third expression. Only one of the second and third expressions is evaluated. Each calculation of a value and the side effect associated with the first expression are sequenced until each value is calculated and the side effect associated with the second or third expression .

§5.19.1 (operator-comma)

Group operators from left to right. A pair of expressions separated by a comma is evaluated from left to right; the left expression is the discarded value of the expression (paragraph 5). Each value calculation and side effect associated with the expression on the left are sequenced up to calculate each value and side effect associated with the correct expression . The type and value of the result is the type and value of the correct operand; the result has the same category of values ​​as its right operand, and is a bit field if its right operand is a glvalue and a bit field. If the value of the right operand is temporary (12.2), the result is temporary.

As for your concern about optimizations that violate this order, no compiler can prevent you from reordering . Compilers should first (try) to follow the standard. Then they can try to make your code faster. They cannot violate the standard just for the sake of performance. This undermines the entire premise of having a standard.

+11
source

This is clearly indicated by the standard that optimized code should behave "as is", it was exactly the code that was written if you rely only on standard behavior.

Since the standard requires that logical operators be evaluated from left to right, optimization (compatible) cannot change the order of evaluation.

+6
source

Source: https://habr.com/ru/post/989749/


All Articles