C/C++ strict-aliasing
最近发现了一个奇怪的编译参数-fno-strict-aliasing,好奇之下做了一点研究;
重点参考Understanding C/C++ Strict Aliasing;
所谓的aliasing就是多个变量指向同一块内存,变量之间互为别名;
strict-aliasing是一种编译器希望开发者遵守的规则:虽然C/C++变量可以随便赋值(强制类型转换),但也请你们收敛一点,别太天马行空了;
如果开发者按照这个规则写代码了,编译器就可以做更好的代码优化,比如这个例子:
void foo(double *dblptr) {anint = 1;*dblptr = 0;bar(anint); }
如果开发者能够注意不要把int*转成double*,bar(anint)可以直接优化成bar(1);
但没有任何约束不允许这样做,因而编译器不敢做这样的优化,只能在bar(anint)将anint传入bar之前加一条汇编指令再读一下anint的值;
如果开发者确定自己的代码遵守这样的规则了,可以在编译时加一个优化参数-fstrict-aliasing,这个参数在gcc的-O2、-O3、-Os优化级别下都是默认开启的。
然后我对Understanding C/C++ Strict Aliasing文中的两个主要例子做了一下测试:
例子一:
#include <stdio.h>int anint;void bar(int a) {printf("%d\n", a); }void foo(double *dblptr) {anint = 1;*dblptr = 0;bar(anint); }int main() {foo((double*)&anint);return 0; }
编译器版本 | 编译参数 | 结果 |
gcc 4.4.7 | g++ | 0 |
g++ -O3 | 1 | |
g++ -O3 -fno-strict-aliasing | 0 | |
gcc 4.8.5 | g++ | 0 |
g++ -O3 | 1 | |
g++ -O3 -fno-strict-aliasing | 0 | |
gcc 7.3.0 | g++ | 0 |
g++ -O3 | 1 | |
g++ -O3 -fno-strict-aliasing | 0 |
可以看到,这个case被gcc编译器优化坏了,可以用-fno-strict-aliasing规避;
例子二:
#include <iostream> #include <iomanip>using namespace std;typedef unsigned int uint32_t; typedef unsigned short uint16_t;uint32_t swaphalves(uint32_t a) {uint32_t acopy = a;uint16_t *ptr = (uint16_t*)&acopy;// can't use static_cast<>, not legal.// you should be warned by that.uint16_t tmp = ptr[0];ptr[0] = ptr[1];ptr[1] = tmp;return acopy; }int main() {uint32_t a;a = 32;cout << hex << setfill('0') << setw(8) << a << endl;a = swaphalves(a);cout << setw(8) << a << endl; }
编译器版本 | 编译参数 | 结果 |
gcc 4.4.7 | g++ |
00000020 00200000 |
g++ -O3 |
00000020 00000020 |
|
gcc 4.8.5 | g++ |
00000020 00200000 |
g++ -O3 |
00000020 00200000 |
|
gcc 7.3.0 | g++ |
00000020 00200000 |
g++ -O3 |
00000020 00200000 |
发现这个case有点意思,只在4.4版本的编译器上会出现问题,高版本编译器上已经修正了。
没有精力再深入研究,就到此为止。
最后再贴上strict aliasing的规则说明,下面这篇文章给出了较好的中文翻译,而且作者显然比我研究的更深入,我就直接抄过来了:
https://blog.csdn.net/dbzhang800/article/details/6720141
- 兼容类型(指相同类型?)或差别仅在于signed、unsigned、const、volatile的类型(比如 const unsigned long *和 long*)
- 聚合类型(struct或class)或联合类型(union)可以alias它们所包含的类型(比如 int 和 包含有int的结构体(包括间接包含))
- 字符类型(char *、signed char*、unsinged char*)可以 alias 任何类型的指针
- [C++] 基类的类型(可能带有const、volatile等cv修饰)可以alias派生类的类型
转载于:https://www.cnblogs.com/ZisZ/p/9105383.html
C/C++ strict-aliasing相关推荐
- strict aliasing
strict aliasing一文中将这些条文允许alias总结如下: 1.兼容类型(指相同类型?)或差别仅在于signed.unsigned.const.volatile的类型(比如 const u ...
- GCC strict aliasing – 嫉妒就是承认自己不如别人
GCC strict aliasing – 嫉妒就是承认自己不如别人 GCC strict aliasing 事情是这样的.我们对tair(淘宝的分布式Key/Value系统)动了一次大手术,更换了网 ...
- Understanding C/C++ Strict Aliasing
Understanding C/C++ Strict Aliasing 深入理解C/C++中的`Strict Aliasin`规则 or - Why won't the #$@##@^% compil ...
- strict alias 的含义
Alias 的定义 一个指针叫做另一个指针的 alias (别名)如果这两个指针都指向相同的地址或对象. 在C99标准里,建立一个与原类型不同的别名是非法的.这叫做 strict aliasing 规 ...
- C/C++ Strict Alias 小记
什么是Aliasing? 理解strict aliasing一文中这样描述: 当两个指针指向同一块区域或对象时,我们称一个指针 alias 另一个指针. strict aliasing一文中这样描述: ...
- python3.7源码分析-字典
python字典 Dictionary object implementation using a hash table ,通过描述可知,python的字典就是实现了一个hash表. Python字典 ...
- How to Fix an App that Crashes in Release but n...
2019独角兽企业重金招聘Python工程师标准>>> 今天在测试app时,发现app store上版本有奔溃现象,但是直接用xcode跑本地程序没问题.猜测release& ...
- 严格的别名规则是什么?
当询问C中常见的未定义行为时 ,人们有时会参考严格的别名规则. 他们在说什么? #1楼 正如Doug T.已经写过的附录一样,这是一个简单的测试用例,可能会用gcc触发它: 检查 #include & ...
- 【GCC】gcc警告选项汇总--编辑中|gcc编译选项
目录 前言 请求或取消警告选项 GCC编译选项 参考原文:https://blog.csdn.net/qq_17308321/article/details/79979514 前言 警告:不是错误的, ...
最新文章
- java猜拳_求一个java猜拳游戏程序
- regex 正则表达式_使用正则表达式(Regex)删除HTML标签
- 值得推荐的微软技术公众号推荐
- springboot2 使用hikaridatasource 并测试_基于Spring Boot 2.x的后端管理网站脚手,源码免费分享...
- 开源XDesigner ORM 框架设计
- 信息奥赛一本通(1120:同行列对角线的格)
- webpack4.0各个击破(7)—— plugin篇
- python 解析pb文件_将tensorflow模型打包成PB文件及PB文件读取方式
- USB2.0学习笔记连载(四):安装Cypress官网套件
- python 怎么得到图像深度图 软件_Python为8bit深度图像应用color map
- HTTP请求头headers
- Treedp贪吃的九头龙详解
- pdf编辑器免安装版_墙裂推荐!功能强大的PDF编辑器最新免安装版!
- gitlab代码查看行数
- python自动化 2 对象定位(1)
- 树状图JQuery.ztree插件的使用
- MBA提前面试——第一章 提面总论
- SpringCloud+SpringBoot b2b2c 电子商务平台涉及的技术、运营方案
- java计算机毕业设计宠物店管理系统设计与实现(附源码、数据库)
- 将base64编码格式数据转化为图片
热门文章
- oracle查询表实际大小,简要分析估算oracle表的大小
- javascript 克隆/clone:Object.assign
- js模块化:require、import和export
- 【若依(ruoyi)】table定制列宽
- Linux 利用yum源安装php7.0+nginx
- 手机浏览器android2.,QQ浏览器Android 2.6:畅享版云浏览器大变身
- php画图取色,procreate怎么取色
- html 复制文本按钮,js实现点击按钮复制文本功能
- 五、朴素贝叶斯分类算法
- 用 Python 做数据处理必看:12 个使效率倍增的 Pandas 技巧(上)