Home > Back-end >  Are both expressions evaluated when using ternary operator?
Are both expressions evaluated when using ternary operator?

Time:05-30

I was practicing some Leetcode problems and I ran into this unexpected runtime error. I'm doing some signed integer operations and trying to set my input negative (i.e. 5 => -5 and -8 => -8)

However, in the case of a INT_MIN input when using a ternary operator, I get an integer overflow. Using an if statement, I don't.

x = x < 0 ? x : x * -1;

>>> runtime error: negation of -2147483648 cannot be represented in type 'int'

vs.

if (x > 0)
    x *= -1;

>>> no problems with this one

Leetcode says "Compiled with gcc 8.2 using the gnu99 standard." for the language info. Is this expected behavior for all versions of C? My naive expectation was that a ternary operator was just syntactic sugar for normal control flow, but clearly I'm wrong on that

CodePudding user response:

No. The spec requires that only one of the operands after the ? is evaluated. From 6.5.15 of the C99 spec:

The first operand is evaluated; there is a sequence point after its evaluation. The second operand is evaluated only if the first compares unequal to 0; the third operand is evaluated only if the first compares equal to 0; the result is the value of the second or third operand (whichever is evaluated), converted to the type described below. If an attempt is made to modify the result of a conditional operator or to access it after the next sequence point, the behavior is undefined.

CodePudding user response:

It's a compiler bug.

The error message is generated by the sanitizer enabled with -fsanitize=undefined flag. The sanitizer adds runtime checks that emit error message whenever Undefined Behavior is invoked. It looks that there was an error in older versions of this diagnostic look.

The other branch should not be evaluated as described in the other answer. The issue was present till GCC 10.1 and it was fixed in GCC 10.2.

See https://godbolt.org/z/e5KWGsPfK

The list of bugfixes in this release is found at bugdixes. It's difficult to say which one is actual fix of the issue.

  •  Tags:  
  • c
  • Related