The order of evaluation of arguments in a function call is unspecified. The compiler can evaluate them in whichever order it might decide on.
From the C99 standard 6.5.2.2/10 "Function calls/semantics":
The order of evaluation of the function designator, the actual arguments, and
subexpressions within the actual arguments is unspecified, but there is a sequence point
before the actual call.
If you need to ensure a particular ordering, using temporaries is the usual workaround:
int i;
for(i=0;i<5;i++) {
int tmp = i;
int tmp2 = i++;
res(tmp2,tmp);
}
Even more important (since it results in undefined behavior, not just unspecified behavior) is that you generally can't use an operand to the increment/decrement operators more than once in an expression. That's because:
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 read only to determine the value to be stored. (6.5/2 "Expressions")