副作用,序列点和未定义的行为

时间:2015-10-09 16:55:11

标签: c

我在书中读到以下声明:

n = ((i++) > (j)?(i++):(j));

这本书声称假设i> j,n有一个意想不到的值而且我增加了两倍。
我不明白为什么n在这个陈述之后有一个期望值。 我读了许多关于未定义行为的例子,所以这里是我的理论(不是书的解释,因为没有&#t; t)并且告诉我是否我和#39;对了:

  

首先,(i ++)> (j)被评估,我可能会或可能不会增加   然而。
假设我> n,(i ++)应该被评估。 我们不知道   我是否已经增加,这就是为什么这整个   声明未定义。我们不确定是否会退回i或i + 1。

现在问题在于我的理论是正确的 - 为什么我们不知道  我是否已经增加?如果将这行代码写成if语句,我很确定我必须先增加。那么为什么化合物会有所不同呢?

谢谢。

1 个答案:

答案 0 :(得分:5)

?:运算符引入了一个序列点,因此这里没有未定义的行为。

评估

(i++) > (j) 并应用i++的副作用。如果(i++) > (j)的结果为真,则再次评估(i++),否则再次评估(j)

i++在增量之前评估i 的值。所以,假设i > j,然后评估

n = i++ > j ? i++ : j;

以下情况属实:

n = iorig + 1
i = iorig + 2

修改

Chapter and verse

6.5.15条件运算符
...
4评估第一个操作数; 评估与评估之间存在一个序列点 评估第二或第三操作数(以评估者为准)。第二个操作数 仅当第一个比较不等于0时才计算;第三个操作数仅在以下情况下进行评估 第一个比较等于0;结果是第二个或第三个操作数的值 (无论哪个被评估),转换为下述类型。 110) 110)条件表达式不会产生左值。