anjruu
anjruu

Reputation: 1264

Does the following chained assignment cause Undefined behavior?

Does the following code invoke undefined behavior in C?

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

I know that the following does invoke UB:

a = b = a++;

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

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

However, the first snippet does not violate this clause. A coworker says that statement a = b = a+1 can mean either

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

or

b = a + 1;
a = b;

I think that due to the "right-to-left" associativity of =, it always must mean a = (b = (a+1)), not

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

I'm not positive, though. Is it UB?

Upvotes: 6

Views: 361

Answers (4)

John Bollinger
John Bollinger

Reputation: 180276

Here is C99's full list of sequence points (adapted from C99, Annex C):

  • during a function call, after the arguments have been evaluated 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 a full declarator;
  • at he end of a full expression (an initializer, the expression in an expression statement, the expression in a return statement, each of the expressions in a for statement, or the controlling expression of an if, switch, while, or do statement);
  • immediately before a library function returns;
  • after the actions associated with each formatted input/output function conversion specifier;
  • immediately before and immediately after each call to a comparison function; and also between any call to a comparison function and any movement of the objects passed as arguments to that call (refers to bsearch() and qsort().

Considering your code in that light:

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

there are sequence points

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

The whole of a = b = (a + 1) is a single expression statement, and it contains no internal sequence points. However, it does not violate the prohibition against an object having its value modified more than once between sequence points: a and b are each modified exactly once in the whole statement.

Upvotes: 4

Sourav Ghosh
Sourav Ghosh

Reputation: 134336

IMHO, a = b = a+1 is well-defined.

Here. you're not changing the value of a, just using it, in case of a+1.

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

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

Upvotes: 12

Serge Ballesta
Serge Ballesta

Reputation: 148965

a = b = a + 1; is the same as :

b = a + 1;
a = b;

You do not change the value of the left hand side in the right hand sides, so it is well defined.

Upvotes: 3

Gopi
Gopi

Reputation: 19864

a = a++;

is different compared to

a = a+1;

In the second case you are not modifying the value of a by doing a+1 whereas in the first case the value of a is being changed which will lead to undefined behavior.

Upvotes: 2

Related Questions