It dereferences to the third element when I'm trying to do it inside printf(), where I also try to dereference that pointer with post and pre-increment.
Here's my code:
#include <stdio.h>
int main()
{
int arr[4] = {1, 2, 3, 4};
int *ptr = &arr[0];
printf("ptr = %p, &arr[0] = %p\n", ptr, &arr); // same addrs
printf("*ptr = %d\n", *ptr); // 1, as expected
// PROBLEM IS HERE:
printf("%d, %d, %d\n", *ptr, *ptr++, *++ptr); // 3, 2, 2
return 0;
}
I've tried funny things like adding elements to an array, changing order of expressions in printf to, but it gave me another confusing answer:
*++ptr, *ptr++, *ptr // 3, 1, 1
But, when I tried printfs in sequence, so to say:
printf("*ptr = %d\n", *ptr);
printf("*ptr++ = %d\n", *ptr++);
printf("*++ptr = %d\n", *++ptr);
Everything worked as expected.
What I expected from initial script in the last printf:
So then, why did I got 3, 2, 2?
Your program is invoking undefined behavior, which means anything can happen, so that you cannot rely on any particular behavior. What actually happens can depend on several things, such as which compiler you are using, which version of the compiler, what settings you are using for the compiler, etc.
The reason why the behavior is undefined is because §6.5 ¶2 of the ISO C11 standard states the following:
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.
There is no sequence point between the evaluation of the individual arguments of a function call. This means that in your program, the arguments *ptr
, *ptr++
and *++ptr
of your printf
function call are unsequenced with respect to each other. Two of those arguments (*ptr++
and *++ptr
) change the value of ptr
as a side-effect, and all three of those arguments use ptr
in a value computation. Therefore, the behavior of your program is undefined according to the paragraph of the ISO C standard quoted above.
See this related question for further information:
Why are these constructs using pre and post-increment undefined behavior?