SPC-order
Synopsis
Expressions that depend on order of evaluation were found.
Enabled by default
Yes
Severity/Certainty
Medium/High

Full description
One and the same variable is changed in different parts of an expression with an unspecified evaluation order, between two consecutive sequence points. Standard C does not specify an evaluation order for different parts of an expression. For this reason different compilers are free to perform their own optimizations regarding the evaluation order. Projects containing statements that violate this check are not easily ported to another architecture or compiler, and if they are they might be difficult to debug. Only four operators have a guaranteed order of evaluation: logical AND (a && b) evaluates the left operand, then the right operand only if the left is found to be true; logical OR (a || b) evaluates the left operand, then the right operand only if the left is found to be false; a ternary conditional (a ? b : c) evaluates the first operand, then either the second or the third, depending on whether the first is found to be true or false; and a comma (a , b) evaluates its left operand before its right. This check is identical to MISRAC++2008-5-0-1_a, MISRAC2004-12.2_a, MISRAC2012-Rule-1.3_i, MISRAC2012-Rule-13.2_a, CERT-EXP30-C_a.
Coding standards
- CERT EXP10-C
Do not depend on the order of evaluation of subexpressions or the order in which side effects take place
- CERT EXP30-C
Do not depend on order of evaluation between sequence points
- CWE 696
Incorrect Behavior Order
- MISRA C:2004 12.2
(Required) The value of an expression shall be the same under any order of evaluation that the standard permits.
- MISRA C:2012 Rule-1.3
(Required) There shall be no occurrence of undefined or critical unspecified behaviour
- MISRA C:2012 Rule-13.2
(Required) The value of an expression and its persistent side effects shall be the same under all permitted evaluation orders
- MISRA C++ 2008 5-0-1
(Required) The value of an expression shall be the same under any order of evaluation that the standard permits.
Code examples
The following code example fails the check and will give a warning:
int main(void) {
int i = 0;
i = i * i++; //unspecified order of operations
return 0;
}
The following code example passes the check and will not give a warning about this issue:
int main(void) {
int i = 0;
int x = i;
i++;
x = x * i; //OK - statement is broken up
return 0;
}