2

When I compile this code with gcc and run

int a=1;
printf("%d",(a=a+1)+(a=a+1)+(a=a+1));

I expect the result to be 2+3+4=9, but the output is 10.

I know that there is undefined behavior in (++a)+(++a)+(++a) , because the three ++ side effect can be run before all (++a) is evaluated.

But I think the value of a=a+1 is exactly what a is after the assignment is evaluated. So the compiler cannot process three a=a+1 first and use the value in variable a as the value of a=a+1 after all a=a+1 evaluated.

I want to know where is wrong according to the c standard.

sepp2k
  • 363,768
  • 54
  • 674
  • 675
zzh1996
  • 480
  • 4
  • 13
  • 2
    The code has no practical use. Sequence points etc. – Ed Heal Sep 22 '16 at 04:01
  • I am studying compilers and I want to know how compilers work according to the c standard – zzh1996 Sep 22 '16 at 04:04
  • 1
    "But I think the value of a=a+1 is exactly what a is after the assignment is evaluated." Why do you think that? Why would that be any different from `++a`? (Hint: it's not.) – rici Sep 22 '16 at 04:04
  • If you speak gibberish to somebody they try their best to understand. Same with a compiler. It will try its best. – Ed Heal Sep 22 '16 at 04:06
  • 1
    @rici Dont you think there must be an explanation for this unexpected behaviour? – roottraveller Sep 22 '16 at 04:06
  • @rootTraveller: ... so the explanation is that the observer erroneously believes that the assigned object will not be read in order to determine the value of the assignment. But there's no reason to hold that belief, and it may or may not be true for any given instance of an assignment. – rici Sep 22 '16 at 04:16
  • 2
    Each of the `a=a+1` may occur sequentially or in parallel or a bit of both. Lacking sequence points leave an ambiguous outcome. – chux - Reinstate Monica Sep 22 '16 at 04:27
  • "*But I think the value of a=a+1 is exactly what a is after the assignment is evaluated*" You have just defined something that the standard explicitly say is undefined. So that's just your definition and the compiler is under no obligation to agree with it. Apparently, it doesn't. – David Schwartz Sep 22 '16 at 04:34
  • Although this code does not use the `++` operator, the question is equivalent, despite the disclaimer about "I know `(a++) + (a++) + (a++)` is UB"; the assignments `a = a + 1` are equivalent to the prefix `++` and the behaviour is just as undefined because there are no intermediate sequence points in the expression shown and the value of `a` is therefore modified multiple times between sequence points, which is UB. – Jonathan Leffler Sep 22 '16 at 04:40
  • @zzh1996 this gives undefined result in C. And the result can be varied from compiler to compiler. – Waqas Shabbir Sep 22 '16 at 04:40

1 Answers1

1

The assignment operator is not a sequence point. Assuming a is just an identifier (e.g. not a macro argument that might expand to something more complicated) and does not have an atomic type (C11), a=a+1 is identical in semantics to ++a.

I wanted to mark this question as a duplicate of one of the hundreds of ++ operator sequence-point questions, but it seems your question is about why this form isn't different.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711