post increment and post decrement evaluate the value and then modify it.
So the first c will be evaluated as 5 and then c will be decremented so the second and third c are evaluated to 4, the final c is evaluated to 4 and then c is incremented.
Having said that, you can not be sure that this is what will happen on another system. doing multiple reads and modifications to a variable in one expression will exhibit undefined behavior and also the order of evaluation is not guaranteed.
It appears to evaluate from left to right for you (probably on the whim of the developer of your compiler, or the position of the moons of Jupiter).
That printf takes 5 parameters. They are evaluated before calling the function. The first parameter is easy; a string literal. The rest four - X, Y, Z, W - get their values as the compiler sees fit.
X gets value of c.
Y gets value of c.
Z gets value of c.
W gets value of c.
Value of c is incremented after it is copied to W.
Value of c is decremented after it is copied to X.
Post-operators first return a value and then modify the variable approximately like:
1 2 3 4 5
int postdecrement( int * rhs ) {
int temp = *rhs;
*rhs = temp - 1;
return temp;
}
Pre-operators first modify the variable and then return that new value approximately like:
1 2 3 4
int predecrement( int * rhs ) {
*rhs = *rhs - 1;
return *rhs;
}
The order of evaluation of function parameters is not specified by the C++ standard, so you have no idea whether (in this case) parameter 2 will be evaluated before or after parameter 5.
You must never alter the value of the same variable more than once (in the above case, either the ++ or -- alone is ok; but not both.)
disclaimer: don't look for any meaning in the results: the program is undefined, no reasoning can be applied unless documented otherwise by the compiler vendor (which I've never seen happen). The results may be different on another version of the same compiler, with different optimization options, etc. They can can crash if they want to (and I'd rather they did).
1 2 3 4 5 6 7 8 9
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c=5;
printf("%d %d %d %d\n",c--,c,c,c++);
return 0;
}
i am not getting how this is working please explain it!
this is showing answer 5 4 4 4...but how? PS-sorry for a C question!
1 2 3 4 5 6 7 8 9
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c=5;
printf("%d%d%d%d",c--,c,c,c++);
return 0;
}
The compiler you used evaluates arguments from left to right (however other compilers may evaluate arguments from right to left).
So your compiler at first calculated the first argument c--. The result of calculation is the value of variable c before decrement that is 5. The argument expression is a full expression. So the side effect was apllied. c became equal to 4. So as the next arguments are c, c, c++ the results of the expressions are 4, 4, 4.
@vlad from moscow
your explain seems right but when we do calculation data are stored in stack so calculation should be from right to left (LIFO rule for stack)! and at first they are pushed from left to right in the stack!
@vlad from moscow
your explain seems right but when we do calculation data are stored in stack so calculation should be from right to left (LIFO rule for stack)! and at first they are pushed from left to right in the stack!
As @Cubbi pointed out my explanation is not fully correct. The side effects shall be applied before executing any statement in the body of the called function. However it seems as I said in my first post your compiler applied the first side effect before evaluating other subexpressions.
As for the stack then placing values of expressions in the stack and evaluating their values are different things.
"i am not getting how this is working please explain it!"
We can't. The compiler isn't bound to evaluate a series of expressions in any specific order; one compiler may evaluate expressions from right-to-left, another may evaluate expressions from left-to-right, another may evaluate all expressions in a seemingly random order, or even partially evaluate one expression, fully evaluate the next expression, then go back to the previous expression and finish its evaluation. At the end of the day, it all depends on the compiler.
If you want to know which order your compiler evaluates expressions in an implementation-defined context (function parameter list context), check the Assembly output or use breakpoints in debug mode.