block
statement (assignment)
expression
operator (dereference)
operator (post-increment)
variable
expression
variable *lwr = x; lwr++;
This could be be represented with something like this (and this is a very vague approximation of an AST): block
statement (assignment)
expression
operator (dereference)
variable
expression
variable
statement
expression
operator (post-increment)
variable
The second form, that looks this in the source: *lwr++ = x
might look like this in the AST: block
statement (assignment)
expression
operator (post-increment)
operator (dereference)
variable
expression
variable
If these two ASTs are to take the same form in the compilation pipeline, there needs to be some kind of pass that transforms one into the other. operator (post-increment)
operator (dereference)
that might be recognised by a pass. In the former form, the two operators are far apart in the tree, so a pass would have to "look further" to match them up. A single pass likely won't do this, either for (compiler) performance reasons, or for correctness reasons. cmp ecx, 1
je .LBB0_3
vs cmp ecx, 2
jne .LBB0_2
LBB0_3 and LBBO_2 were the same in both outputs (up to alpha renaming).