Could anyone please explain the result of the following C program?
#include<stdio.h>
int main()
{
int i=2;
printf("%d %d %d",i,i++,++i);
return 0;
}
How is the output 4 3 4
?
Could anyone please explain the result of the following C program?
#include<stdio.h>
int main()
{
int i=2;
printf("%d %d %d",i,i++,++i);
return 0;
}
How is the output 4 3 4
?
The order of evaluation of arguments is undefined by the C++ standard; and also, "if a side effect on a scalar object is unsequenced relative to another side effect on the same scalar object, the behavior is undefined".
Therefore, the post-increment and pre-increment on the same scalar value as arguments to the same function call is undefined. Obviously both increments are being done prior to the first and last arguments being evaluated, in your case.
You start with i = 2
. Because of i++
and ++i
, the variable i
is increased by 2 (each ++
adds 1). Therefore, when you are finished, its value is 4.
The syntax i++
says that to use the value if i
before incrementing it. That is why the middle number (which printf
gets from i++
) cannot be 4.
The reason it is 4 3 4 and not something else such as 2 2 4 or 2 3 3 or 4 3 3 has to do with when the ++
operators are evaluated compared to when the parameters of the printf
function are set. One should simply never write code like that, at least not for software that anyone actually has to use.
You have entered the land of Undefined Behaviour. C makes no guarantees about the order in which the arguments being passed to a function are evaluated, especially not varargs functions. The outcome of a statement like this, which is a classic interview question, is "unknown" -- it can change between compiler versions, platforms, etc, and is similar to the question:
int i = 1;
int a[3] = { 1, 2, 3 };
int j = a[i++] - a[++i];
What is j? Answer: it depends on your compiler, version, platform, etc: the one thing you cannot use to deduce it is the C specification.
But you're wondering about the 3, aren't you? That's because your compiler evaluated ++i first, which incremented i
to 3. Then your compiler evaluated i++
, the post increment, which is implemented equivalent to this (in C++, sorry):
int operator ++ (int) { // post-increment indicated by int parameter
int i = *this;
this->operator++();
return i;
}
or in other pseudo code
int tempI = i;
++i;
so what you actually wrote was:
printf("%d %d %d\n", i, (j = i, ++i), ++i);
at the end of evaluating the arguments to pass to printf, i
had the value 4
, but the temporary returned by i++
retained its value of 3.
Hence: 4(i) 3(temp) 4(i)