Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using increment in ternary operator in C

For the example, after I use

int a = 5, b = 6;
x = (a < b) ? a++ : b++;

x gets the value of a, which is 5, and a increments to 6, which is expected.

When I use

a = (a < b) ? a++ : b++;

After this line, a still remains 5.

But

a = (a++ < b++) ? a : b;

a is now 6.

Why is this happening and why isn't increment operator executed in the first case?

EDIT: Just to clarify, I'm asking why this happens when I'm using these lines separately, one by one, not all three in the same time.

like image 396
Pyranth Avatar asked Oct 21 '15 15:10

Pyranth


2 Answers

a = (a < b) ? a++ : b++;

here, we stored a in a, and then incremented it. But it is like

a = a++; // as a<b

which shows undefined behaviour.

a = (a++ < b++) ? a : b;

here, a is being incremented at the time of comparison, so now a is 6, which is stored in a.

like image 94
Mukit09 Avatar answered Sep 26 '22 07:09

Mukit09


Both cases involve undefined behaviour of some sort because you are incrementing a, returning a and assigning to a on the left side within 2 sequence points. 3 would be required for a clearly defined result.

In this case : a = (a < b) ? a++ : b++;

  1. if a is smaller than b
  2. a is returned (value = 5) as the result of the ternary operator
  3. a is incremented (value = 6).
  4. the result of the ternary operator (5) is assigned to the left hand side variable a (over-writing 6)

The order of steps 3 and 4 is not defined. It is equivalent to a = a++;

In this case : a = (a++ < b++) ? a : b;

  1. If a is smaller that b
  2. a and b are incremented (regardless which is smaller)
  3. a is returned as the result of the ternary operator
  4. it is assigned to the left hand side variable a

The order of steps 2 and 3 is not clearly defined.

It's important to keep track of sequence points in such cases. Relevant rules :

  • The 1st expression of ternary operator on the left of ? is sequenced before the 2nd or 3rd expressions. And either of them is sequenced before assignment.
  • The comparison is sequenced before the ?
  • In expressions like a++ the value is returned before incrementing

Undefined behaviour:

  • In expressions like a = a++; there is no sequence point between (post)incrementing a and assigning to a on the left side. Both happen after the original value of a is returned
  • In expressions like a++ ? a : b there is no sequence point between (post)incrementing a and returning a from the ternary operator. Both happen after the ?
like image 26
Manos Nikolaidis Avatar answered Sep 23 '22 07:09

Manos Nikolaidis