0

Can someone please explain why this code is outputing 2 1, I thought post-increment was supposed to be applied after the printf instruction.

#include <stdio.h>

int main() {
  int i=1;
  int *p=&i;
  printf("%d %d\n", *p ,i++);

  return 0;
}
Youssef Bouhjira
  • 1,599
  • 2
  • 22
  • 38
  • 4
    This question is like a demon. Takes all forms & comes everyday! :) – P.P Sep 12 '13 at 20:20
  • Maybe there's a reason for this? – zubergu Sep 12 '13 at 20:22
  • @KingsIndian I don't think I have seen this form before, part of the problem is that this is not really taught well in school(if at all) or in books. It is also not easy to search for this either. – Shafik Yaghmour Sep 12 '13 at 20:24
  • @ShafikYaghmour I have no problem with it being asked everyday. It's probably among the most intriguing C questions when you look at first time. I never downvoted *this* question. Instead I mark as dup. Trust me, I have *numerous forms* of *this* in my 545 consecutive days on SO :) – P.P Sep 12 '13 at 20:30
  • 1
    @KingsIndian [usually it is good to have multiple versions of the same question](http://meta.stackexchange.com/a/32315) and they are asked often b/c it is unintuitive result. – Shafik Yaghmour Sep 12 '13 at 21:42
  • @ShafikYaghmour That's exactly what I did. I voted to close as a dup. – P.P Sep 12 '13 at 21:49
  • This question is not a duplicate. If someone doesn't know the rule, it's impossible to fit it under "undefined behaviour" or "unspecified behaviour" tag. Connections between this question and that @KingsIndian mentioned is obvious when you know there is some. – zubergu Sep 13 '13 at 06:24
  • 1
    @zubergu I don't expect everyone to know the rule. But that doesn't mean this is not a duplicate. The example fairly simple to understand and most users in C tag can easily identify that. I don't consider every minor variation: different variable name, happens in printf/other function calls, etc as different questions. I can't believe you claim this is not a duplicate of that. Just because it doesn't have ` printf("%d %d\n", i ,i++);` means it's not a dup. The printf() statement in question is exactly the same. – P.P Sep 13 '13 at 06:30
  • 2
    &KingsIndian I just claim it's a duplicate if you know it's a duplicate. And that's tautology I like to avoid. – zubergu Sep 13 '13 at 09:57

2 Answers2

4

The order of evaluation of is not specified for this case in the standard and so you can not determine whether *p or i++ will be evaluated first. The C99 draft standard says in section 6.5.2.2 Function calls paragraph 10 says:

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.

This is also undefined behavior because you are modifying i and accessing the previous value of i in another expression within the same sequence point, the draft standard in section 6.5 Expressions paragraph 2 says:

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.72) Furthermore, the prior value shall be read only to determine the value to be stored

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
1

Comma is a sequence point, but not in function calls.
And printf is a function with arguments separated with commas.
In expression like this:
if(i+2,i++). . . comma is a sequence point and assures that expressions will be evaluated from left to right, and final value of expression will be value of rightmost sub-expression. In this case i++.
On the other hand in funcion call:
function(i+1,i++,i--) comma in not a sequence point and any of sub-expressions can be evaluated as first. The only thing sure is that they all be evaluated, but not in any specific order.

zubergu
  • 3,646
  • 3
  • 25
  • 38