子表达式的未定义行为
Undefined behaviour of sub-expressions
这是否会导致未定义的行为,因为计算顺序将未指定?
int i = 0, j = 0, k = 0;
int result = i++ + ++j + k++;
不,求值的结果不依赖于未指定的子表达式的求值顺序。
未定义行为仅在影响同一对象的两个副作用相对未排序,或者同一对象的副作用和值计算未排序的情况下才会发生。前缀和后缀自增的副作用和值计算都显式排序。
的求值顺序是未指定的,但是谁在乎呢?每个操作数作用于一个完全不同的对象。
不,行为是完美定义的:j
递增,然后执行加法,然后i
和k
递增。唯一未指定的是执行i
和k
上的增量的顺序。后置条件为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)
只要保持上述约束,指令就可以按照编译器的喜好重新排序。但是约束保证了结果是格式良好的。
相关文章:
- 编译C++时未定义的引用
- vscode g++链路故障:体系结构x86_64的未定义符号
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 不知道某个东西是否被忽略会引入未定义的行为吗
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 未定义的引用在哪里
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 在 C 和 C++ 中,使用逗号运算符的表达式是否未定义"a = b, ++a;"?
- Boost正则表达式:链接时未定义的引用
- C++后缀表达式未定义与未指定行为
- 编译器在常量表达式中认为未定义的行为方面是否允许回旋余地?
- 评估潜在常量表达式期间的未定义行为
- 如果表达式的中间结果溢出,这是未定义的行为吗
- 当 f & g 修改相同的全局变量时,表达式 f() 的值是否> g() 未定义或未指定?
- 1<<31产生误差;'<<'表达式未定义”;
- 为什么传递特征表达式的临时性会导致访问未定义的内存
- 为什么我得到“操作可能未定义”?c++中的语句表达式
- 子表达式的未定义行为
- 在Arduino IDE中使用正则表达式库时对"longjmp"的未定义引用