Yes and no.
The assignment evaluates the expression "++i" and stores the result in
i, so the result of the expression must be determined before the value
is stored. But the side effect of "++i" is to modify i; that side
effect doesn't need to occur before the assignment modifies i, since
the side effect isn't necessary for determining what the result of
"++i" is going to be.
Using a well-defined example:
j = ++i;
There are several things that must happen here:
(a) Evaluate "j" as an lvalue (i.e., determine its address).
(b) Evaluate "i" to determine its current value.
(c) Determine the result of "++i".
(d) Store the result of "++i" in j (side effect of "=").
(e) Increment i (side effect of "++"").
(f) Determine (and discard) the result of the assignment expression.
Some of these things must occur before other things can happen. For
example, (c) must precede (d). But (e) can occur either before or
after (d); you don't need to modify i to determine what the result of
"++i" is going to be.
In this case, since i and j are separate objects, there's no problem.
In the case of "i = ++i", the two modifications to i are unordered,
and so the behavior is undefined.
The pre-C201X draft:
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1362.pdf>
has a very interesting re-statement of the rules in 6.5 (it helped me
understand what the C90/C99 wording really means):
An _expression_ is a sequence of operators and operands that
specifies computation of a value, or that designates an object or
a function, or that generates side effects, or that performs a
combination thereof. The value computations of the operands of an
operator are sequenced before the value computation of the result
of the operator.
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.
The grouping of operators and operands is indicated by the
syntax. Except as specified later, side effects and value
computations of subexpressions are unsequenced.