表达式求值顺序
Expression evaluation order
我最近被下面的c++代码段弄糊涂了:
#include <cstdio>
int lol(int *k){
*k +=5;
return *k;
}
int main(int argc, const char *argv[]){
int k = 0;
int w = k + lol(&k);
printf("%dn", w);
return 0;
}
看第一行:
int w = k + lol(&k);
直到现在,我认为这个表达式将从左到右进行评估:取k的当前值(在调用lol函数之前为0),然后将其添加到lol函数的结果中。但是编译器证明我错了,w的值是10。即使我把它改成
int w = lol(&k) + k;
的结果仍然是10。我做错了什么?
Tomek
这是因为表达式中的参数是而不是,指定以任何特定顺序求值。
编译器可以自由地先执行参数k
或lol(&k)
。在这个表达式中没有序列点。这意味着参数的副作用可以按任意顺序执行
所以简而言之,没有指定代码是打印5
还是10
。都是有效的输出。
的例外是在布尔表达式中短路,因为&&
和||
是序列点。(见注释)
这段代码的结果是5还是10,取决于函数调用相对于+左侧的求值顺序的选择。
它的行为是不是未定义的,因为函数调用被两个序列点包围。
Plus
根据定义是可交换的,因此示例中的顺序完全是由实现定义的。
mystic 在提到序列点时是正确的。引用维基百科文章(手头没有c++标准):
命令式编程中的序列点定义了A中的任意点一种计算机程序的执行,它保证了所有方面的安全先前评估的效果将被执行,没有副作用后续评价的效果尚未执行。他们是在参考C和c++时经常提到,因为结果有些表达式的求值顺序取决于其子表达式。添加一个或多个序列点是一种方法确保一致的结果,因为这限制了可能性求值顺序
本文还提供了c++中序列点的列表。
相关文章:
- CMake-按正确顺序将项目与C运行时对象文件链接
- 函数调用中参数的顺序重要吗
- (C++)分析树以计算返回错误值的简单算术表达式
- 为什么不;名字在地图上是按顺序排列的吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 在C++中,当表达式涉及对象时,将表达式赋值到对象中时,是否有定义的操作顺序?
- 通过调试来检查C 中单行表达式执行顺序的方法
- 折叠表达式评估顺序
- C++ 和 Java 之间的表达式求值顺序有何不同
- 赋值子表达式的计算顺序
- 按递增顺序枚举代数表达式
- 子表达式求值顺序的不可预测性
- c++ 17表达式求值顺序和std::move
- 布尔表达式的顺序在while循环中重要吗?
- 表达式求值顺序
- 表达式的求值顺序
- if 表达式中的操作顺序是否更改
- 具有逻辑运算符的子表达式的C++求值顺序
- 新的表达式求值顺序(指针赋值)