0

I came across a very interesting fact while executing the following a simple c program:

#include<stdio.h>

int main( )
{
    int k=0;

    printf("%d%d%d", k++, k, ++k);
    return 0;
}

in windows it was showing output as: 1 1 1

but in linux(ubuntu) it was showing as: 1 2 2

why is it so?

swegi
  • 4,046
  • 1
  • 26
  • 45
ABHIDEV
  • 49
  • 1
  • 5

3 Answers3

2

It's undefined behaviour. When there are no / ambiguous sequence points. See this wikipedia article:

http://en.wikipedia.org/wiki/Sequence_point

Dave
  • 3,438
  • 20
  • 13
  • i think u r talking about preference and associativity of operators but i am talking aboutr why behaviour changed for gcc is it the work of parser – ABHIDEV Feb 21 '11 at 14:21
  • This has nothing to do with precedence and associativity, and everything to do with attempting to modify an object more than once between sequence points. – John Bode Feb 21 '11 at 15:22
  • Thanks John. No, I am not talking about precedence and operator associativity. The behaviour in your code fragment is undefined, so GCC can deal with it however it wants. Other compilers are likely to deal with it differently, since there is no "correct" behaviour. – Dave Feb 21 '11 at 15:29
2

There are two problems. First is that the order in which the expressions k++, k, and ++k in the printf call are evaluated is not specified; the compiler is free to evaluate them in any order it sees fit. Second is that an object may not have its stored value updated more than once between sequence points by the evaluation of an expression. Both k++ and ++k attempt to update the value stored at k, and there is no sequence point between those expressions, so the behavior is undefined; any result is permitted.

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • i agree but what if it gives answers like //same code with changes in printf ("%d %d %d",++k,++K,++k);// now in linux it is again showing a totally different behavior it is printing 3 3 3 why?? – ABHIDEV Feb 21 '11 at 14:59
  • 1
    @ABHIDEV: Again, because the behavior is *undefined*. You're trying to update `k` multiple times between sequence points (a `,` in a parameter list does not introduce a sequence point). Once you do that, all bets are off. You will get *a* result, but it may not be the result you expect. Also, don't ever assume that the side effect of `++` or `--` will be applied *immediately* after the expression is evaluated; they may be deferred. For example, given the statement `x = i++ * ++j`, it's possible that the updates to both `i` and `j` may be deferred until after `x` is assigned. – John Bode Feb 21 '11 at 15:21
  • @ABHIDEV: If you want to understand the mechanics of how you're getting those specific values, you can check the generated assembly code (gcc -S) to see the exact sequence of instructions. However, it won't give you any insight into why they were generated in that sequence in the first place. – John Bode Feb 21 '11 at 15:34
  • @ABHIDEV : This thread might help : http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points – Prasoon Saurav Feb 22 '11 at 03:10
0

The standard does not specify an ordering in which the arguments of a routine are evaluated. Writing code that depends on the ordering is not portable.

swegi
  • 4,046
  • 1
  • 26
  • 45