c++ 表达式执行顺序
来源:互联网 发布:2015年人口老龄化数据 编辑:程序博客网 时间:2024/06/02 01:59
计算顺序
在c++中,任何表达式(函数参数,子表达式)中的运算元的计算顺序都是不固定的。对于相同的表达式,编译器可能生成不同计算顺序的指令。
同时,在c++中,没有像从左到右,或从右到左的计算规则(刚接触c++的人,容易将计算顺序与运算符的结合性混淆)。比如表达式:
f1()+f2()+f3()
按加法从左向右的结合性,可以转换为:
(f1() + f2()) + f3()
结合性仅仅提供了,表达式需要计算那些单元,至于这些单元的计算顺序,需要使用其他规则。在本表达式中,f3() ,f2(),f1()的计算顺序是不定的,可能f3()最先计算,也可能,最后计算f3(),或者,先计算f2(),再计算f3()。
计算顺序模型
对于一个表达式,根据运算符的优先级与结合性,生成需要计算的计算单元集合。每两个计算单元有一种顺序关系,根据这种顺序关系,以计算单元为顶点,计算先后关系为边,生成一个有向图。
建立这个有向图之后,进行拓扑排序,即可得到一种执行顺序(因为有向图的拓扑排序不一定唯一,所以,可能产生多种执行顺序;如果这多种执行顺序影响程序的执行结果,则会造成程序行为undefined)
以f1()+f2()+f3()为例,
生成计算单元集合:{f1(), f2(), f3(),f1() + f2(), (f1() + f2()) + f3()}
根据规则,生成有向图:(***********)
- 有向图拓扑排序
- 生成执行顺序
Sequenced-before rules
任何一个表达式或子表达式的计算,可能包含两个计算单元(0,1,2):
- 值计算:
计算表达式返回的值。需要读取对象的值 - side effect:
修改对象,调用IO函数
两个计算单元的计算顺序关系包含以下四种:
- A before B, B必须在A执行完之后执行
- B before A, A必须在B执行完之后执行
- A B unsequenced, A和B可以任意顺序执行,内部指令也可以混杂执行
- A and B are indeterminably-sequenced, A先于B 或 B先于A
部分sequenced-before rules:
- 每一个完整表达式一定先于下一条完整表达式
- 一个表达式的值计算(not side effect)一定先于,这个表达是值计算结果的值计算
- 函数调用,参数表达式执行早于函数体中的表达式执行
- .........
Undefined behavior
对同一个对象有side effect 的两个计算单元,顺序不确定:
i = ++i + i++; // undefined behavior i = i++ + 1; // undefined behavior (but i = ++i + 1; is well-defined) f(++i, ++i); // undefined behavior f(i = -1, i = -1); // undefined behavior
对同一个对象的,一个side effect 单元与一个值计算单元,顺序不确定:
cout << i << i++; // undefined behavior a[i] = i++; // undefined behavior
- c++ 表达式执行顺序
- C,C++表达式求值顺序(执行点,副作用)
- for循环中表达式执行顺序for(Expression a;Expression b;Expression c)
- C#.net Page执行顺序
- C#.net Page执行顺序
- C#.net Page执行顺序
- C#.net Page执行顺序
- Linux c多线程执行顺序
- T-SQL 各个表达式的执行顺序
- for表达式的语句执行顺序?
- javaSE _表达式的执行顺序
- c语言表达式求值顺序
- C,C++表达式求值顺序
- C,C++表达式求值顺序
- C,C++表达式求值顺序
- C,C++表达式求值顺序
- C,C++表达式求值顺序
- C,C++表达式求值顺序
- 数据库模型设计——主键的设计
- Java小数点位数保留问题
- 求单独出现的数,strncpy的优化
- JNI 常用函数
- 使用collections工具类实现斗地主中的洗牌和发牌过程
- c++ 表达式执行顺序
- Xcode断点调试变量都变成nil
- linux安装并配置SVN指南
- 【BZOJ4372】烁烁的游戏 动态树分治
- Spring JMS——MessageConverter介绍
- web前端教程:使用javascript实现多级联动效果
- mysql 行锁
- DayDayUP_Python自学记录[15]_python execl 读写进阶
- 进程的地址空间