使用三元运算符时是否对两个表达式都进行了评估?

Are both expressions evaluated when using ternary operator?

我正在练习一些 Leetcode 问题,我 运行 遇到了这个意外的运行时错误。我正在做一些带符号的整数运算并尝试将我的输入设置为负数(即 5 => -5 和 -8 => -8)

但是,在使用三元运算符输入 INT_MIN 的情况下,我会遇到整数溢出。使用 if 语句,我不这样做。

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

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

对比

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

>>> no problems with this one

Leetcode 说“使用 gnu99 标准用 gcc 8.2 编译。”对于语言信息。这是所有版本的 C 的预期行为吗?我天真的期望是三元运算符只是正常控制流的语法糖,但显然我错了

没有。规范要求仅评估 ? 之后的一个操作数。来自 C99 规范的 6.5.15:

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.

这是一个编译器错误。

错误消息是由启用了 -fsanitize=undefined 标志的消毒程序生成的。消毒程序添加了运行时检查,每当调用 Undefined Behavior 时都会发出错误消息。看起来这个诊断外观的旧版本有错误。

另一个分支不应按照另一个 中的描述进行评估。该问题在 GCC 10.1 之前一直存在,并在 GCC 10.2 中得到修复。

https://godbolt.org/z/e5KWGsPfK

此版本中的错误修复列表可在 bugdixes 中找到。很难说哪一个是问题的实际解决方案。