子表达式的未定义行为

时间:2011-09-16 20:14:52

标签: c++ undefined-behavior

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

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

8 个答案:

答案 0 :(得分:5)

不,评估结果不依赖于未指定的子表达式评估顺序。

未定义的行为仅在这种情况下发生,如果影响同一对象的两个副作用相对于彼此无序或副作用,并且同一对象的值计算未被排序。前缀和后缀增量的副作用和值计算都是明确排序的。

答案 1 :(得分:4)

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

规则是如果您多次修改变量,则结果未指定。你的例子中没有这样做。

答案 4 :(得分:0)

这里很好,因为你没有两次使用相同的变量。

你所拥有的相当于:

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

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

答案 5 :(得分:0)

此处结果将始终为1. j,k和i的值均为1.此外,请注意,多个变量声明的分隔符为,,而不是;

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

下面:

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)

只要保持上述约束,指令就可以像编译器那样重新排序。但是约束条件保证了结果的良好形成。