-3

Can someone explain how this operation works?

#include <stdio.h>

int main()
{
    int a = 5;
    int b, c;

    c = (a = 3) + (b = a + 2) - (a = 2);

    printf("%d %d %d", a, b, c);

    return 0;
}

The output is 2 5 5

Parentheses go first and start from the left.

c = 3 + (b = 3 + 2) - (a = 2)

c = 3 + 5 - 2

And the output should be 2 5 6

KnFantasy
  • 21
  • 3

2 Answers2

4

The 3 assignments in (a = 3) + (b = a + 2) - (a = 2) are a problem as it is undefined behavior as they are unsequenced: may occur in any order or even at the same time creating bus conflicts.

Best to re-write this poor code.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • I didn't intend to write this. Just wodering how this work. So what make this 3 assignments actually have a certain order to produce this output? – KnFantasy Jul 17 '21 at 13:43
  • @KnFantasy There is no certain assignment order. Knowing that, how might _you_ re-write it to clearly identify the assignment order you want? – chux - Reinstate Monica Jul 17 '21 at 13:48
  • @Monica I re-edit my guess. I don't want any order. If there's no certain order, then why this code always produce the same output on my computer. So it must follow a certain order, right? – KnFantasy Jul 17 '21 at 14:04
  • @KnFantasy "So it must follow a certain order, right? " --> No. "this code always produce the same output on my computer" is a premature conclusion. Re-compile with a different compiler, optimization level or a different version, results may differ. **C** does not specify any certain behavior here with this poor code. The point of code is to write such that it compiles and works the same today and tomorrow and on your computer and others, This code offers no such promise. – chux - Reinstate Monica Jul 17 '21 at 14:11
  • @Monica OK but now in this compiler and with all these settings, is there any way to find out the exact order which can result in this output. Sorry for my meanless insistence. – KnFantasy Jul 17 '21 at 14:35
  • @KnFantasy "to find out the exact order which can result in this output." --> Yes, look at the executable code, dis-assembly it and study it. As C code, there is no certain solution. – chux - Reinstate Monica Jul 17 '21 at 14:37
  • @Monica By the way, is it useless to write and find out the order of a complicated expression? – KnFantasy Jul 17 '21 at 14:47
  • @KnFantasy Not useless to understand the order of a complicated well defined expression. It is far less use to find out the order of a undefined sequence expression such as this. – chux - Reinstate Monica Jul 17 '21 at 15:25
1

C doesn’t force left-to-right evaluation of arithmetic expressions - each of a = 3, b = a + 2, and a = 2 may be evaluated in any order (they are said to be unsequenced with respect to each other). Since two of those expressions modify the value of a, the result of b = a + 2 can vary based on the compiler, optimization settings, even the surrounding code - the result could be 7, 5, 2, or something else completely.

The behavior of modifying a multiple times and using it in a value computation without an intervening sequence point is undefined, meaning the compiler isn’t required to handle the situation in any particular way. It may give you the result you expect, but it doesn’t have to. The result doesn’t have to be consistent from build to build, or even from run to run.

This should give the results you would expect based on a left-to-right reading of your expression.

a = 3;
b = a + 2;      // b = 5
c = a + b - 2;  // c = 6
a = 2;
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • Do you mean that if I write a + b + c. C could evaluate a + b first or b + c first? – KnFantasy Jul 17 '21 at 14:21
  • @KnFantasy: Each of `a`, `b`, and `c` can be evaluated in any order. Arithmetic `+` is left associative, so `a + b + c` is *parsed* as `(a + b) + c` - the result of `a + b` will be added to the result of `c`. However, `a + b` doesn’t have to be evaluated before `c`. – John Bode Jul 17 '21 at 14:50
  • So in previous expression, the side effects of `a = 3`, `b = a + 2`, and `a = 2` are evaluated in any order? `a = 3` and `a = 2` certainly return the value of 3 and 2. In the output, `a` either get the value of `3` or `2`. `b` could be `7`, `5` or `4`. and `c` could be `8`, `6` or `5`. None of these match your `7`, `5` ,`2`? – KnFantasy Jul 17 '21 at 15:31
  • @KnFantasy: Typo on my part. Point is, the result isn’t guaranteed to be consistent or predictable. – John Bode Jul 17 '21 at 15:59
  • @KnFantasy Importantly C allows `a = 3`, `b = a + 2`, and `a = 2` to be evaluated simultaneously or randomly sequenced or .... This creates conflict as to what `a` has in the end as well as what `b` is. It also may crash code due to a bus fault of writing two values to `a` at the same time. There is no specified order, just chaos. It is _undefined behavior_. – chux - Reinstate Monica Jul 17 '21 at 22:05