a
is an array, foo
is a function, and i
is an int
.
a[++i] = foo(a[i-1], a[i]);
Would
The behavior is undefined because the expressions a[++i]
, a[i-1]
, and a[i]
are unsequenced relative to each other.
Chapters and verses:
6.5 Expressions
...
2 If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.84)
...
6.5.2.2 Function calls
...
10 There is a sequence point after the evaluations of the function designator and the actual arguments but before the actual call. Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.94)
...
6.5.16 Assignment operators
...
3 An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment,111) but is not an lvalue. The type of an assignment expression is the type the left operand would have after lvalue conversion. The side effect of updating the stored value of the left operand is sequenced after the value computations of the left and right operands. The evaluations of the operands are unsequenced.
84) This paragraph renders undefined statement expressions such as
while allowingi = ++i + 1; a[i++] = i;
...i = i + 1; a[i] = i;
94) In other words, function executions do not ‘‘interleave’’ with each other
...
111) The implementation is permitted to read the object to determine the value but is not required to, even when the object has volatile-qualified type.
C 2011 Online Draft