We have, or have seen, a situation where the assignment expression participates in the operation. This is usually accompanied by some unexpected problems. Today I saw a strange piece of code:
#include <stdio.h>int main () {int a =5; int b = (a=2) + (a=3);p rintf ("%d%d\n", A, b); return 0 ;}
At first glance, it seems that the answer is clear, after the sequential operation, the value of a is the value of 3,b is 5. An experienced programmer will surely see that the computational process here is an undefined behavior (Undefined behavior). In the simplest case, there is no way to determine which expression in parentheses will be executed first.
parentheses can only change the union of operators, and cannot change the order of evaluation of an expression. This order is dependent on the compiler. So the value of a is 2 or 3 is not deterministic.
The result of this code in GCC (Ubuntu) is
3 6
And the result of running under clang (MAC) is
3 5
why is that? What's the matter?
View the assembly code they generated
gcc ... movl $5, -8(%RBP)//a=5MOVL $2, -8(%RBP)//A =2MOVL $3, -8(%RBP)//a =3MOVL-8(%RBP),%eax//eax = a addl%eax,%eax//eax = eax + eax movl%eax,-4(%RBP)//b = EAX...CLANG...MOVL $5, -8(%RBP) MOVL $2, -8(%RBP)//A =2MOVL $3, -8(%RBP)//A =3MOVL $5, - A(%RBP)//b =5...
In the understanding of GCC
A = (b=c)// will be rewritten as b=CA=b// so for a = (b=c) + (d=e) // will be rewritten as B == + +d// when B and D are the same value, the variable space is reused,
In the understanding of clang
A = (b=c) + (d=e)// is rewritten as i=b=CJ=d=ea=i+J// So the sum of the right expression value of the assignment symbol is directly obtained.
This concludes that the return value of an assignment expression is the value to the right of the assignment symbol.
However, in some special cases, using some compilers may not get the results you want. So we should try to avoid using the value of an assignment expression to participate in the operation.
Note: Although the value of a is 3 in two cases, this does not mean that the evaluation order of an expression is left to right.
For more information about the compiler evaluation order, refer to this article
What is the return value of an assignment expression in C language?