Evaluation of an expression may produce side effects. At specific points during execution, known as sequence points, all side effects of previous evaluations have completed, and no side effects of subsequent evaluations have yet taken place.
The C Standard, Section section 6.5 [ISO/IEC 9899:2011], states:
...
Programs cannot safely rely on the order of evaluation of operands between sequence points. In this noncompliant code example, the order of evaluation of the operands to the +
operator is unspecified.:
Code Block | ||||
---|---|---|---|---|
| ||||
a = i + b[++i]; |
...
These examples are independent of the order of evaluation of the operands and can be interpreted in only one way.:
Code Block | ||||
---|---|---|---|---|
| ||||
++i; a = i + b[i]; |
...
The order of evaluation for function arguments is unspecified.:
Code Block | ||||
---|---|---|---|---|
| ||||
func(i++, i); |
...
This solution is appropriate when the programmer intends for both arguments to func()
to be equivalent.:
Code Block | ||||
---|---|---|---|---|
| ||||
i++; func(i, i); |
This solution is appropriate when the programmer intends for the second argument to be one greater than the first.:
Code Block | ||||
---|---|---|---|---|
| ||||
j = i++; func(j, i); |
...
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Compass/ROSE |
|
| Can detect simple violations of this rule. It needs to examine each expression and make sure that no variable is modified twice in the expression. It also must check that no variable is modified once, then read elsewhere, with the single exception that a variable may appear on both the left and right of an assignment operator. | ||||||
| EVALUATION_ORDER | Can detect the specific instance where a statement contains multiple side effects on the same value with an undefined evaluation order because, with different compiler flags or different compilers or platforms, the statement may behave differently. | |||||||
| evalordr | Fully implemented. | |||||||
GCC |
|
| Can detect violations of this rule when the | ||||||
| 35 D | Fully implemented. | |||||||
PRQA QA-C |
| 0400 [U] | Fully implemented. | ||||||
Splint |
|
|
|
...
CERT C++ Secure Coding Standard | EXP30-CPP. Do not depend on order of evaluation between sequence points |
CERT Oracle Secure Coding Standard for Java | EXP05-J. Do not write more than once to the same variable within an expression |
ISO/IEC TR 24772:2013 | Operator Precedence/Order of Evaluation [JCW] Side-effects and Order of Evaluation [SAM] |
MISRA - C:2012 | Rule 12.1 (advisory) |
Bibliography
[ISO/IEC 9899:2011] | Section 6.5, "Expressions," and Annex C, "Sequence Points" |
[Summit 2005] | Questions 3.1, 3.2, 3.3, 3.3b, 3.7, 3.8, 3.9, 3.10a, 3.10b, and 3.11 |
[Saks 2007] |
...