子表达式的未定义行为

发布于 2024-12-05 04:25:05 字数 111 浏览 0 评论 0原文

这是否会导致未定义的行为,因为评估顺序未指定?

int i = 0, j = 0, k = 0;
int result = i++ + ++j + k++;

Does this result in undefined behaviour because the order of evaluation will be unspecified?

int i = 0, j = 0, k = 0;
int result = i++ + ++j + k++;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

北笙凉宸 2024-12-12 04:25:05

不,求值结果不取决于子表达式的未指定求值顺序。

未定义行为仅在影响同一对象的两个副作用相对于彼此不排序或者同一对象的副作用和值计算不排序的情况下才会发生。前缀和后缀增量的副作用和值计算都是显式排序的。

No, the result of the evaluation doesn't depend on the unspecified order of evaluation of the sub-expressions.

Undefined behavior only occurs in this situation if two side effects that affect the same object are unsequenced relative to each other or a side effect and a value computation of the same object are unsequenced. The side-effect and value computation of both prefix and postfix increment are explicitly sequenced.

丢了幸福的猪 2024-12-12 04:25:05

评估的顺序指定,但谁在乎呢?每个操作数作用于一个完全不同的对象。这里没有什么未定义的。

The order of evaluation is unspecified, but who cares? Each operand acts on a completely distinct object. Nothing undefined here.

醉城メ夜风 2024-12-12 04:25:05

不,行为是完全明确定义的:j 递增,然后执行加法,然后 ik 递增。唯一未指定的是 ik 上增量的执行顺序。后置条件为 i==1j==1k==1result==1

No, the behavior is perfectly well-defined: j is incremented, then addition is performed, then i and k are incremented. The only thing that is unspecified is the order in which the increments on i and k are performed. The postcondition is i==1, j==1, k==1, result==1.

妄想挽回 2024-12-12 04:25:05

规则是,如果多次修改变量,则结果是不确定的。在你的例子中你还没有这样做。

The rule is that the results are unspecified if you modify a variable more than once. You haven't done that in your example.

柳絮泡泡 2024-12-12 04:25:05

这里很好,因为您不会两次使用同一个变量。

你所拥有的相当于:

int i = 0, j = 0, k = 0;
++j;
int result = i + j + k;
++i;
++k;

如果你改为 int result = i++ + ++i + i++; 那么你就会遇到问题,因为增量的顺序未指定,并且你依赖于根据该命令。

It's fine here because you don't use the same variable twice.

What you have is equivalent to:

int i = 0, j = 0, k = 0;
++j;
int result = i + j + k;
++i;
++k;

If you were to have instead int result = i++ + ++i + i++; then you'd have a problem because the order of the increments is unspecified, and you depend on that order.

云之铃。 2024-12-12 04:25:05

这里结果将始终为 1。j、k、i 的值将全部为 1。另外,请注意多个变量声明的分隔符是 ,,而不是 ; :

int i=0, j=0, k=0;

Here result will be always 1. The values of j, k, and i will be all 1. Also, note that separator for several variable declaration is ,, and not ;:

int i=0, j=0, k=0;
念三年u 2024-12-12 04:25:05

不,这是一个经典/众所周知的 C++ 序列点问题,请参阅此处的链接了解更多详细信息
http://en.wikipedia.org/wiki/Sequence_point

No, it's a classic/well known c++ sequence point issue, see link here for much more detail
http://en.wikipedia.org/wiki/Sequence_point

断爱 2024-12-12 04:25:05

这里:

int result = i++ + ++j + k++;

也是等价的:

<SP>
(a1)int t1 = i;     // i++ part one: The result of post-increment is the original value
(a2)     i = i + 1; // i++ part two: the increment part separated from the result
(b1)     j = j + 1;
(b2)int t2 = j;     // The result of pre-increment is the new value
(c1)int t3 = k;     // k++ part one: The result of post-increment is the original value
(c2)     k = k + 1;
(d) int t4 = t1 + t2;
(e) int t5 = t3 + t4;    
(f) int result = t5;
<SP>

约束是:

(a1) is before (a2)
(a1) is before (d)
(b1) is before (b2)
(b2) is before (d) 
(c1) is before (c2)
(c1) is before (e)
(d)  is before (e)
(e)  is before (f)

只要保持上述约束,指令就可以按照编译器的喜好重新排序。但约束保证了结果的格式良好。

Here:

int result = i++ + ++j + k++;

Is Equivalent too:

<SP>
(a1)int t1 = i;     // i++ part one: The result of post-increment is the original value
(a2)     i = i + 1; // i++ part two: the increment part separated from the result
(b1)     j = j + 1;
(b2)int t2 = j;     // The result of pre-increment is the new value
(c1)int t3 = k;     // k++ part one: The result of post-increment is the original value
(c2)     k = k + 1;
(d) int t4 = t1 + t2;
(e) int t5 = t3 + t4;    
(f) int result = t5;
<SP>

The constraints are:

(a1) is before (a2)
(a1) is before (d)
(b1) is before (b2)
(b2) is before (d) 
(c1) is before (c2)
(c1) is before (e)
(d)  is before (e)
(e)  is before (f)

As long as the above constraints are maintained the instructions can be re-ordered as much as the compiler likes. But the constraints guarantee that the result is well formed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文