The comma used when calling a function does not come with a sequence point.
Therefore, this code *ptr, *(++ptr)
invokes undefined behavior, because it attempts to access ptr twice between sequence points, for other purposes than to determine what value to assign to ptr.
This is defined by C11 6.5/2, in the following gibberish text:
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.
In our case, the side effect (changing ptr with ++ in *(++ptr)
) is unsequenced in relation to the value computation of the same object (*ptr
).
And since it is undefined behavior, anything can happen. Since your program does "something", it behaves as expected (or rather, as "unexpected").
In addition, the order of evaluation of function parameters is unspecified, so you cannot know whether the first or second parameter in the function call gets evaluated first. The order can differ not only between compilers, but between source code lines in the same program. The compiler can evaluate them in any order it likes and it does not need to document how.