basic increment decrement operator!

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
10
#include <stdio.h>
#include <stdlib.h>

int main()
{
   int c=5;
    printf("%d%d%d%d",c--,c,c,c++);
    return 0;
}
closed account (z05DSL3A)
There is no real way of explaining it, as it will exhibit undefined behavior.
i know it uses stacks to execute but how it is really giving output?
closed account (z05DSL3A)
Are you asking how the value of c is changed during the execution of printf("%d%d%d%d",c--,c,c,c++);?

yes!
<snip -- I confused myself.>
Last edited on
i also thats why i am asking what the hell is going on there?
closed account (z05DSL3A)
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.

https://www.securecoding.cert.org/confluence/display/seccode/EXP30-C.+Do+not+depend+on+order+of+evaluation+between+sequence+points
closed account (jwkNwA7f)
-- is like typing - 1,
++ is like typing + 1

BTW, wouldn't that put out
4556

I think that is what you meant. Hope this helped!
Last edited on
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.)

This stackoverflow.com includes quotes of the relevant bit of the standard:
function parameter evaluation order
http://stackoverflow.com/questions/9566187/function-parameter-evaluation-order

Andy

PS In my earier attempt at a post I started to go on about the related issue of sequence points then realised I'd gone in the right direction.

When it comes to ++ and --, you cannot use them more than once between two sequence points without undefined behavior.
http://en.wikipedia.org/wiki/Sequence_point

Note that sequence points and function parameter order evaluation applies to more than just operator++ and operator--

Further reading:
Undefined Behavior and Sequence Points
http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points
Last edited on
let's torture some compilers!

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;
}


Linux/gcc: 6 5 5 5
Linux/clang: 5 4 4 4
IBM/gcc: 5 5 5 4
IBM/xlc: 5 4 4 4
Sparc/cc: 5 5 5 4


more references (specifically for C)
http://en.cppreference.com/w/c/language/eval_order
http://c-faq.com/expr/seqpoints.html and the previous chapters
Last edited on
Visual C++ 2010 is giving me 5 5 5 5
MinGW GCC 6 5 5 5 (same as Cubbi's result for Linux/gcc)
And DigitalMars C++ is giving me 6 6 6 5

Andy

@hellcoder

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.

Do you have satisfied by the explanation?:)
Last edited on
The argument expression is a full expression. So the side effect was apllied.

That is incorrect.
@Cubbi


The argument expression is a full expression. So the side effect was apllied.

That is incorrect


Is not it? I need to see the standard...
@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!
@hellcoder

@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.
closed account (zb0S216C)
hellcoder wrote:
"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.

Wazzak
Last edited on
Topic archived. No new replies allowed.