从花式swap引出的pointer aliasing问题
上次,一个同学问我,你知不知道可以不用引入中间变量就可以实现swap?
我说,我知道,可以用加减法或者异或实现,像是这样
void mySwap(int &x,int &y) {
x=x+y;
y=x-y;
x=x-y;
}
或者这样
void mySwap(int &x,int &y) {
x=x^y;
y=x^y;
x=x^y;
}
但这种花式swap没什么意义,而且具有风险,那就是如果参数引用的是同一个变量,将产生错误的结果0。
这种问题叫pointer aliasing
另外C++中也有类似于C语言的restrict关键字,当为参数加上__restrict修饰时,编译器可以据此作出一些编译优化,但是是基于这些指针都是引用不同变量的。如果程序员引用了同样的变量,是undefined behavior(未定义行为)。
来看下面所示的代码片段
int sum(int* __restrict x,int* __restrict y) {
*x=;
*y=;
return *x+*y;// return 7
}
int main () {
int x=,y=;
printf("%d\n",sum(&x,&y));
return ;
}
这代码片段在开不开启编译优化的情况下,都能正确地返回7。
当我们不使用变量y,只使用x,并且不开启任何编译优化的情况下,下面的代码片段能够正确地返回8
int sum(int* __restrict x,int* __restrict y) {
*x=;
*y=;
return *x+*y;// return 8
}
int main () {
int x=;
printf("%d\n",sum(&x,&x));
return ;
}
但是当我们在上述代码片段基础上,一旦开启了编译优化(只需-O级),下面的代码片段将错误地返回7
int sum(int* __restrict x,int* __restrict y) {
*x=;
*y=;
return *x+*y;// return 7
}
int main () {
int x=;
printf("%d\n",sum(&x,&x));
return ;
}
原因很简单,因为编译器根据restrict假设了两个指针指向不同变量,作出了编译优化,在编译阶段便已经知道应当返回7。而我们在实际过程仍然令两个指针指向同一变量,这是未定义行为导致的结果错误。
从花式swap引出的pointer aliasing问题的更多相关文章
- 由swap引出的局部变量,形参和指针的小问题
1.第一种实现swap函数的方法是: swap(int a,int b) { Int c = a;a = b;b =c; } 这表面一看确实是实现了整数a,b的交换,当拿来用时发现,结果并不是我们想要 ...
- [翻译]类型双关不好玩:C中使用指针重新解释是坏的
原文地址 Type punning isn't funny: Using pointers to recast in C is bad. C语言中一个重新解释(reinterpret)数据类型的技巧有 ...
- c查漏补缺
restrict 要理解什么是restrict,首先要知道Pointer aliasing:指两个或以上的指针指向同一数据,例如: ; int *a = &i; int *b = &i ...
- 使用freerdp远程连接Windows桌面
之前使用的是rdesktop,但是由于其不支持NLA认证,便不能登录公司的电脑.为此,现在使用freerdp——这是package的名字,实际的可执行程序是xfreerdp.使用如下的命令行即可实现远 ...
- LeetCode 75. Sort Colors(排序颜色)
Given an array with n objects colored red, white or blue, sort them so that objects of the same colo ...
- ”危险“的restrict与GCC的编译优化
restrict是C99标准中新添加的关键字,对于从C89标准开始起步学习C语言的同学来说(包括我),第一次看到restrict还是相当陌生的.Wikipedia给出的解释如下: In the C p ...
- c99标准的restrict关键字
参考自restrict restrict解释 restrict关键字出现于C99标准,wiki上的解释restrict from wiki. In the C programming language ...
- restrict关键字
值得注意的是,一旦你决定使用restrict来修饰指针,你必须得保证它们之间不会互相重叠,编译器不会替你检查. 关键字restrict有两个读者.一个是编译器,它告诉编译器可以自由地做一些有关优化的假 ...
- ”危险“的RESTRICT与GCC的编译优化(编程者对编译器所做的一个“承诺”:使用restrict修饰过的指针,它所指向的内容只能经由该指针修改)
restrict是C99标准中新添加的关键字,对于从C89标准开始起步学习C语言的同学来说(包括我),第一次看到restrict还是相当陌生的.Wikipedia给出的解释如下: In the C p ...
随机推荐
- oracle expdp和impdp常用命令选项
一.expdp导出数据库 1.按用户导出 expdp scott/tiger@orcl DIRECTORY=oracle_dmp dumpfile=bak.dmp schemas=scott vers ...
- 队列工厂之(MSMQ)
最近vs2017神器正式版发布让人很是激动,vs2017支持了很多语言的开发,从前端-后端-底层的支持,堪称是工具中的神器:netcore我喜爱的架构之一也得到了大力的宣传,应群友的邀请将在队列工厂( ...
- 1715: [Usaco2006 Dec]Wormholes 虫洞
1715: [Usaco2006 Dec]Wormholes 虫洞 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 501 Solved: 278[Sub ...
- 腾讯云数据库团队:MySQL AHI 实现解析
MySQL 定位用户记录的过程可以描述为:打开索引 -> 根据索引键值逐层查找 B+ 树 branch 结点 -> 定位到叶子结点,将 cursor 定位到满足条件的 rec 上:如果树高 ...
- linux计算程序运行时间
转自: http://www.cnblogs.com/NeilHappy/archive/2012/12/08/2808417.html #include <sys/time.h> int ...
- Spring-Mybatis配置多数据源
可以参考: http://www.cnblogs.com/ityouknow/p/6102399.html 需要一个DatabaseConfiguration类,实现 TransactionManag ...
- 富文本,NSAttributedString,当需要改变的内容有相同的时候的解决方法
在开发的过程中可能会遇到富文本展示,例如:一行文本,前面是题后面是答案,题和答案用不同的颜色字体,但是答案的内容在题总也有,这时候用平常的方法就会展示错误,因为把题中的内容改变了颜色二实际答案却没有改 ...
- SQL AlawaysOn 之五:ISCSI共享磁盘
用于存放SQL数据库 1.安装服务 2.安装完成后要求重启计算机.添加该功能要配置计算机,如果是正式服务器,那种不能关机太久的服务器,请慎用. 重启之后看到文件和储存服务,击击进去 3.看到ISCSI ...
- iOS开发之计算文字尺寸
/** * 计算文字尺寸 * * @param text 需要计算尺寸的文字 * @param font 文字的字体 * @param maxSize 文字的最大尺寸 */ - ( ...
- 自动生成并导出word文档
今天很荣幸又破解一现实难题:自动生成并导出word文档 先看页面效果: word效果: 代码: 先搭建struts2项目 创建action,并在struts.xml完成注册 <?xml vers ...