This is a stupid question. :)
[EDIT: stupid or not, this turned out to be a C++ peculiarity question, see UPDATE_2]
Suppose we have:
int a = 0; // line 1
int b = ++a; // line 2
What happens in line 2 is (note, numbers are just markers and do not specify exact order):
= [1: write result of (3) to result of (2)]
/\
[2: take "b" l-value] [3: convert result of (4) to an r-value ]
|
[4: take "a" l-value, "increment" and return it]
The "write" in (4) is "ordered" before the "read" in (3), and since there are no sequence points between, the side-effect is not guaranteed to happen before (3) (there is also a "read" inside (4) itself, but ordered before "write", so that does not yield UB).
So, where is the error in the above?
[UPDATE, aimed at not seasoned sequence-point lawyers :)]
In other words the problem is:
There seems to be a "competition" whether the l-value-to-r-value conversion ("read") or increment ("write") side-effect takes place first.
In C, that would give an UB, according to JTC1/SC22/WG14 N926 "Sequence Point Analysis"* (see, for example, EXAMPLE 5:
int x,y; (x=y) + x; // UB
).Note this would not be a case should postincrement be used since (3) and (4) will constitute a single [(3): take "a" l-value, convert it to r-value and return that r-value] with the "write" side-effect delayed until somewhere before the next sequence point
_
(*) This looks like the cleanest systematic rationale for the topic given by the C99 Standards Committee members.
[UPDATE_2]
Lesson learned: never judge C++ by C rules :)). I did exactly that wondering why the N926 (which cleanly describes the C99 way of things) was "not clear enough" on the topic of preincrements yielding l-values.
The question arises, how would one build a similar rationale for C++, as there isn't one, since even in the C case just interpreting the standard is pretty hard, and the C++ language standard is much more complicated and obscure.