此 C 代码是否会导致未定义的行为?

Does this C code result in Undefined Behavior?

我知道:

int b = 1, c = 2, d = 3, e = 4;
printf("%d %d %d", ++b, b, b++);

导致未定义的行为。自

Modifying any object more than once between two sequence points is UB. Undefined behavior and sequence points

但我不知道是否:

int b = 1, c = 2, d = 3, e = 4;
printf("%d", b++ + ++c - --d - e--);

也是UB吗?

我认为 increment/decrement 运算符将首先计算,因为它们之间的优先级是从右到左,因为关联性。然后算术运算符将从左到右求值。

这将是

(b) + (c + 1) - (d - 1) - (e)

that is, 1 + (2 + 1) - (3 - 1) - (4)

= (2 - 4)

= -2

对吗?

But I don't know if: ... is also UB?

不是,但是你的推理很模糊。

What I think is that increment/decrement operators will evaluate first because of the precedence, between them right to left since the associativity . Then arithmetic operators will be evaluated left to right.

优先级决定了结果的计算方式。它没有说明副作用的顺序。

当副作用(b 的存储值已递增,e 的存储值已递减)何时可观察到时,没有等效的优先级告诉您 在声明中。您所知道的是,变量在 next 语句之前(即通过 ;)获得了新值。

所以,这是明确定义的原因是它不依赖于那些副作用


为了避免陷入困境,我故意挥舞着语言,但我应该澄清一下:

  • "during the statement" 真正的意思是"在下一个序列点"之前
  • “在 next 语句之前 (... ;)” 真正的意思是“ 在下一个序列点

Order of evaluation:

  1. There is a sequence point after the evaluation of all function arguments and of the function designator, and before the actual function call.

所以真的副作用是在调用printf之前提交的,所以早于语句末尾的;

表达方式有天壤之别

b++ + ++c - --d - e--

(很好),

x++ + ++x - --x - x--

(严重未定义)。

它没有使用 ++-- 使表达式未定义。它甚至没有在同一个表达式中使用 ++-- 两次。不,问题是当您使用 ++-- 修改表达式中的变量时, 您还尝试在其他地方使用相同变量的值在同一个表达式中,并且没有中间序列点。

考虑更简单的表达式

++z + z;

现在,显然子表达式 ++z 将递增 z。那么问题来了,+ z 部分使用的是 z 的旧值还是新值?而答案是没有答案,这就是这个表达式未定义的原因。

记住,像 ++z 这样的表达式做 而不是 只是意味着,“取 z 的值并加 1”。他们的意思是,“取 z 的值并加 1,并将结果存回 z”。这些表达式具有 副作用 。副作用是不确定性问题的根源。