The behavior is well defined because calling a function counts as a sequence point, and each statement within the function is also a sequence point. It is not the same as if the body of the function were put in its place.
First inc
is called. This invokes a sequence point.
Within the function, the statement return ++(*k)
is executed, which first evaluates the containing expression. This results in i
in main
getting incremented to 1, and the expression evaluates to the new value of i
, which is 1. The return
statement returns that value from the function, and the completion of that statement is another sequence point, so the side effect of incrementing i
is guaranteed to be complete.
Back in main
, the value of 1 returned from inc
is then assigned to i
.
Had you instead done this:
i = ++(*ptr);
That would be undefined behavior because there is no sequence point between assigning to i
and the side effect of incrementing i
via *ptr
.