Does the following chain assignment result in Undefined behavior?

Does the following code cause undefined behavior in C ?

 int a = 1, b = 2; a = b = (a + 1); 

I know the following calls UB:

 a = b = a++; 

The reason is that it violates the following sentence from the standard:

Between the previous and the next point in the sequence, the object must have its stored value, changed no more than once by evaluating the expression. In addition, the previous value should only be consulted to determine the value to be stored.

However, the first fragment does not violate this section. The employee says that the statement a = b = a+1 can mean either

 a = a + 1; b = a + 1; 

or

 b = a + 1; a = b; 

I think because of the “right to left” associativity = it should always mean a = (b = (a+1)) , not

 a = a + 1; b = a + 1; 

I am not sure, however. Is it UB?

+6
source share
4 answers

IMHO, a = b = a+1 is clearly defined.

Here. you do not change the value of a , just using it, in the case of a+1 .

To be explicit, according to the “right to left” associativity of the = operator, you can break down the above as,

 b = a + 1; //a does not change here, only the value is used. a = b; 
+11
source

Here is a complete list of sequence points (C99, Appendix C) C99:

  • during a function call after evaluating the arguments and before any part of the function body is executed;
  • at the end of the first operand of the following operators: && , || , ?: , ;
  • at the end of the full declarator;
  • at the end of the full expression (initializer, expression in the expression of the expression, expression in the return statement, each of the expressions in the for expression or control expression if , switch , while or do );
  • before returning the library function;
  • after the actions associated with each formatted output / output function conversion specifier;
  • immediately before and immediately after each call to the comparison function; and also between any call to the comparison function and any movement of objects passed as arguments for this call (applies to bsearch() and qsort() .

Given your code in this light:

 int a = 1, b = 2; a = b = (a + 1); 

there are sequence points

  • after a = 1 (full declarator)
  • after b = 2 (full declarator)
  • at the end of the second statement. (full expression)

All a = b = (a + 1) is one expression of the expression and does not contain internal points of the sequence. However, this does not violate the prohibition on an object whose value changes more than once between points in the sequence: a and b change exactly once in the whole expression.

+4
source

a = b = a + 1; matches with:

 b = a + 1; a = b; 

You do not change the value of the left side on the right side, therefore it is clearly defined.

+3
source
 a = a++; 

differs from

 a = a+1; 

In the second case, you do not change the value of a , making a+1 , while in the first case, the value of a changes, which will lead to undefined behavior.

+2
source

Source: https://habr.com/ru/post/987419/


All Articles