子表达式的未定义行为

Undefined behaviour of sub-expressions

本文关键字:未定义 表达式      更新时间:2023-10-16

这是否会导致未定义的行为,因为计算顺序将未指定?

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

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

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

的求值顺序是未指定的,但是谁在乎呢?每个操作数作用于一个完全不同的对象。

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

规则是,如果您多次修改一个变量,则不指定结果。在您的示例中您还没有这样做。

这里没有问题,因为您不会两次使用相同的变量。

等于:

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

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

这里的结果总是1。j k和i的值都是1。另外,注意几个变量声明的分隔符是,,而不是;:

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

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

此处:

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)

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