博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[C++] "a = b + (b = a);" Vs "a = 1 + (b=a);"
阅读量:5291 次
发布时间:2019-06-14

本文共 1285 字,大约阅读时间需要 4 分钟。

最早是在微博上看到这样一个swap函数。

void swap(int& a,int& b){    a = b + 0*(b = a);}

那么我也来讨论讨论这样的表达式有什么行为。当然这里是我认为的答案,也不敢保证完全正确,因为C++实在是太复杂了,完全不敢说知道的面面俱到。

下面来看这两个C++表达式,a和b都是int类型。

a = b +  0 * (b=a);  // exp 1a = 1 +  0 * (b=a);  // exp 2

exp 1就是原来swap函数的实现方法,这个比较明显了。因为C++里面规定了子表达式的计算顺序和side effect的发生顺序是不确定的。

另外: "Furthermore, the prior value shall be accessed only to determine the value to be stored."  也就是说 c = c + 1;是没有问题的,因为读取c的值是为了计算最后写入c的值。

但 a = b + 0 * (b=a); 就有问题了。因为第一个读取b的操作,不是为了计算写b时用的值。所以这是一个undefined behavior。

参考这里获得C++03标准的原文()

 

那么exp 2呢? 

a = 1 + 0 * (b=a);

一样,在C++03里面是undefined behavior。读取a的值不仅仅是为了计算写a的值。比如说可以有两种执行顺序

第一种:

1. 计算(b=a)这个表达式的值。

2. store b的值

3. 计算整个表达式的值,并store a

或者第二种:

1. 计算(b=a)这个表达式的值。

2. 计算整个表达式的值,并且store a

3. store b的值。因为这个时候a的值已经改变了,那么实际b的值就不确定了。

 

但是,要知道C++是一种恐怖的语言,到了C++12的时候,标准里面对于assignment加了一句话。

In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.

这句话不能保证exp 1的行为,因为计算+号的两个子表达式的顺序依然不确定。但是对于exp 2来说,就是well defined behavior。其执行顺序只能是这样:

1. 计算b的左值和a的右值。

2. 完成store b;

3. 完成计算(b=a)的值。

4. 计算a的左值和 1+0*(b=a) 的右值。

5. store a

6. 计算 a = 1 + 0 * (b=a) 的值。

参考这里获得更多信息()

 

OK,我的结论就是这样子的了。

转载于:https://www.cnblogs.com/aoaoblogs/archive/2012/08/11/2633332.html

你可能感兴趣的文章
第五周学习进度
查看>>
事务的应用
查看>>
Excel Vlookup多条件查询 , 列转行
查看>>
浅谈JS继承
查看>>
2018-2019-2 20175224 实验一《Java开发环境的熟悉》实验报告
查看>>
元素的offsetParent offsetLeft offsetTop属性
查看>>
NOI2015
查看>>
生成器表达式
查看>>
第三天运算符--三元操作符
查看>>
C#学习笔记-输入数据判断(int、double、string)
查看>>
uva 10881
查看>>
ubuntu node.js Binaries方式安装(二进制文件安装)
查看>>
Ansible Ad-Hoc Commands
查看>>
sql 修改字段小记
查看>>
现代浏览器的工作原理
查看>>
完美CSS文档的8个最佳实践
查看>>
扒一扒.NET Core的环境配置提供程序
查看>>
python基础之ATM-2
查看>>
《20170926-构建之法:现代软件工程-阅读笔记》
查看>>
js中for循环闭包问题记录
查看>>