The standard says:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. /26/
Except as indicated by the syntax /27/ or otherwise specified later (for the function-call operator () , && , || , ?: , and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified.
So:
1.) a[p1++] = b[p2++]
: It is guaranteed that the statement is evaluated correctly and gives the expected result. This is because each variable is modified only once and the result does not depend on the time when the actual increment of both variables is done.
2.) a++ + ++a
: It is not guaranteed that the side effect (increment) is performed before the second usage of a
. Hence this expression can give the value a + (a+1)
or (a+1) + (a+1)
or a + (a+2)
depending on when your compiler performs the side effect increments of the original variable.