-3

I printed the above line. But I got the result as 65.How does I increment and print despite the fact that I is incremented at the second time??

int i=5; 
printf("%d%d",i,i++); 
sabarish
  • 141
  • 12
  • I couldn't figure out the question that you have mentioned in your comment when I posted my question.Now too when I searched for printf in C, there are 250 pages.How could you expect beginners like us to search for printf rather than posting questions??Does posting doubts pose any problems for the people to answer?? – sabarish Dec 10 '12 at 08:48
  • 2
    This question in this very form (with `printf` and `++i`) is asked here at least twice a week. It is weird though that despite that fact, people still keep repeating the irrelevant answers about "unspecified order of evaluation"... – AnT stands with Russia Dec 10 '12 at 08:55

3 Answers3

3

Your printf call produces undefined behavior. It is illegal to modify i (in i++) and at the same time perform an independent read of i without an intervening sequence point.

Various "orders of evaluation" do not matter here. All attempts to explain the behavior of this code based on the "orders of evaluation" or what happens "before" and what happens "after" are absolutely incorrect. The behavior is simply undefined. End of story.

As far as the C language itself is concerned, this code can print "Kill all humans!", crash the program, format your hard drive or simply refuse to compile.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • I've seen this claim before. Why is it legal C to bork out and do something entirely unrelated? I, as many others, thought that it was only the evaluation order that was undefined. Care to elaborate? – Emil Vikström Dec 10 '12 at 08:46
  • 1
    @Emil Vikström: Well, the very definition of the concept of "undefined behavior" allows anything to happen. The popular mistake other posters here make is that they assume that the behavior is *unspecified* (that would be the consequence of unspecified order of evaluation). However, in this example the situation is significantly worse that that. The behavior is *undefined*, not merely *unspecified*. And when the behavior is *undefined*, absolutely anything can formally happen. – AnT stands with Russia Dec 10 '12 at 08:51
  • @emil: to expand on what Andrey said (hopefully I'm not confusing the issue), an example where order of evaluation is an issue: say you have a function like `int inc( int* p)` that increments `*p` and returns the incremented value. Calling `printf("%d%d\n", i, inc(&i))` would not be undefined behavior because there's a sequence point when `inc()` is called, but the `printf()` could print either `56` or `66` since it's unspecified whether `i` is evaluated before or after `inc(&i)`. The expression `i++` doesn't provide a sequence point. That's why the original example has undefined behavior. – Michael Burr Dec 10 '12 at 09:11
  • AndreyT, I'm still not following. Isn't it just the evaluation *order* that is undefined? That would mean that any *order* is valid. Or am I missing something? Maybe I'm asking the wrong question? – Emil Vikström Dec 20 '12 at 12:33
  • Michael Burr, yeah, I know that the order is not defined. Thanks :-) – Emil Vikström Dec 20 '12 at 12:34
  • 1
    @Emil Vikström: No. It is more than just evaluation order that is undefined. Situations with undefined evaluation order are covered by the concept of ***unspecified** behavior*. This code is *qualitatively* different from *unspecified behavior*. This code produces ***undefined** behavior*. This is the next step up to the ultimate level of "undefinedness". The code is not guaranteed to compile. And the code is allowed to behave unpredictably in absolutely all respects. – AnT stands with Russia Dec 20 '12 at 19:34
  • Thanks for explaining! I will make sure to read more about this. – Emil Vikström Dec 21 '12 at 06:26
1

The ANSI C99 ISO/IEC 9899:1999 standard says

6.5.2.2 Function calls The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.

Constantin
  • 8,721
  • 13
  • 75
  • 126
  • But When there is no incrementation in printf statement,the order is from left to right.How is that possible??Does it change when I introduce I++?? – sabarish Dec 10 '12 at 08:42
  • No, the order of evaluation is always _unspecified_ - regardless if there are incrementations, decrementation, function calls or whatever. The order of output is from left to right, but that doesn't mean the compiler has to evaluate the arguments in this order also. – Constantin Dec 10 '12 at 08:46
0

as you just discovered, the order of evaluation is unspecified. The compiler is free to evaluate the arguments in any order. (In your case, i++ is evaluated before i.)

Johan Kotlinski
  • 25,185
  • 9
  • 78
  • 101
  • But When there is no incrementation in printf statement,the order is from left to right.How is that possible??Does it change when I introduce I++?? – sabarish Dec 10 '12 at 08:43
  • Having both `i` and `i++` as arguments to the same function is **undefined behavior**. This is much stronger than “unspecified” and allows the compiler not just to pick any order, but also to make demons fly out of your nose. The relevant clause in the C99 is 6.5:2 and you may find information at http://en.wikipedia.org/wiki/Sequence_point – Pascal Cuoq Jul 25 '13 at 16:27
  • As far as I can see, standard says that order of evaluation is unspecified, not undefined behavior... indeed there is no reason why such printf statement should make demons fly out of the nose... – Johan Kotlinski Jul 26 '13 at 22:55