But I am afraid some compilators reverse the two operands
These expressions must be evaluated left-to-right. This is covered in the standard about the operators &&
, ||
, ?
, and ,
. They specifically mention the order, as well as enforced sequence points.
§5.14.1 (Logical AND)
The &&
operator groups left-to-right. The operands are both contextually converted to 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.
§5.15.1 (Logical OR)
The ||
operator groups left-to-right. The operands are both contextually 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.
§5.16.1 (Conditional operator)
Conditional expressions group right-to-left. The first expression is contextually 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. Only one of the second and third expressions is evaluated. Every value computation and side effect associated with the first expression is sequenced before every value computation
and side effect associated with the second or third expression.
§5.19.1 (Comma operator)
The comma operator groups left-to-right. A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded value
expression (Clause 5). Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression. The type and value of the result are the type and value of the right operand; the result is of the same value category
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 a temporary (12.2), the result is that temporary.
Regarding your concern about optimizations violating this order, no compilers are not allowed to change the order. Compilers must first and foremost (try to) follow the standard. Then they can try to make your code faster. They may not violate the standard just for the sake of performance. That undermines the entire premise of having a standard.
g++ -O3
does not break specifications. It might break your code, but not the C++ standard. – Felid-Ofast
, which says "Disregard strict standards compliance". I think most of this will concern floating point operations. – Felid