“-fstrict-aliasing”表示启用严格别名规则,“-fno-strict-aliasing”表示禁用严格别名规则,当gcc的编译优化参数为“-O2”、“-O3”和“-Os”时,默认会打开“-fstrict-aliasing”。

什么是严格别名规则?gcc对严格别名的定义:

In particular, an object of one type is assumed never to reside at the same address as an object of a different type, unless the types are almost the same.

即,编译器假定相同的内存地址绝不会存放不同类型的数据,否则即破坏了严格别名规则。

别名的定义可理解为:同一内存地址有不同的名称,比如:

int m = 0x20190101;

int* p1 = &m;

int *p2 = &m;

int *p3 = p2;

int n = m;

这里“&m”、“p1”、“p2”和“p3”均是同一内存地址的别名,但n不是,因此涉及严格别名,是和指针相关的。

下列代码,如果使用“-O2”、“-O3”或“-Os”编译,并且加不“-fno-strict-aliasing”,则“*s”的结果是未定义的,不同的编译器可能产生不同的结果,即使同一编译器也可能运行时结果不尽相同:

#include <stdio.h>

int main() {

int m = 0x12345678;

short* s = (short*)&m; // 使用C++的方式也不可:short* s = reinterpret_cast<short*>(&m);

printf("%x\n", *s);

return 0;

}

gcc-4.1.2上运行情况,可以看到每次结果都不相同:

> g++ --version

> g++ -g -o e e.cpp -O2

> ./e

6590

> ./e

590

> ./e

ffffb590

怎么解决严格别名问题?采用类型相关(type-punning),手段是采用联合体union,比如下面这种类型相关的用法是安全的:

#include <stdio.h>

union X {

int m;

short s;

};

int main() {

X x;

x.m = 0x12345678;

short s = x.s;

printf("%x\n", s);

return 0;

}

然而,下列用法仍然是不安全的(多版本gcc实测正常,也未有“dereferencing type-punned pointer will break strict-aliasing rules”编译告警,但gcc手册指出结果可能不符合预期):

#include <stdio.h>

union X {

int m;

short s;

};

int main() {

X x;

x.m = 0x12345678;

short* s = &x.s;

printf("%x\n", *s);

return 0;

}

下列代码的结果也是未定义的(多版本gcc实测也正常,同样未有编译告警,但gcc手册指出结果是未定义的):

#include <stdio.h>

union X {

int m;

short s;

};

int main() {

int m = 0x12345678;

short s = ((X*)&m)->s;

printf("%x\n", s);

return 0;

}

如果担心风险,可加上编译参数“-fno-strict-aliasing”,但这会阻止gcc相关的优化。不过下列别名总是安全的:

1) “unsigned int”别名“int”,其它类似

2) “char”别名其它任何类型

严格别名规则“-fstrict-aliasing”和“-fno-strict-aliasing”及类型双关的更多相关文章

  1. linux中sudoers别名规则

    /etc/sudoers 配置文档中别名规则 别名规则定义格式如下: Alias_Type NAME = item1, item2, ... 或 Alias_Type NAME = item1, it ...

  2. Python 代码优化常见技巧

    代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化.扩展以及文档相关的事情通常需要消耗 80% 的工作量.优化通常包含两方 ...

  3. [转] Python 代码性能优化技巧

    选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化 ...

  4. Python 代码性能优化技巧

    选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化 ...

  5. Yii CModel中rules验证规则[转]

    array( array(‘username’, ‘required’), array(‘username’, ‘length’, ‘min’=>3, ‘max’=>12), array( ...

  6. Theano2.1.14-基础知识之理解为了速度和正确性的内存别名

    来自:http://deeplearning.net/software/theano/tutorial/aliasing.html Understanding Memory Aliasing for ...

  7. Yii CModel中rules验证规则

    array( array(‘username’, ‘required’), array(‘username’, ‘length’, ‘min’=>3, ‘max’=>12), array( ...

  8. ES 10 - Elasticsearch的索引别名和索引模板

    目录 1 索引模板概述 1.1 什么是索引模板 1.2 索引模板中的内容 1.3 索引模板的用途 2 创建索引模板 3 查看索引模板 4 删除索引模板 5 模板的使用建议 5.1 一个index中不能 ...

  9. Item 9: 比起typedef更偏爱别名声明(alias declaration)

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 我确信我们都同意使用STL容器是一个好主意,并且我希望在Item ...

随机推荐

  1. 编程,计算data段中的第一组数据的3次方,结果保存在后面一组dword单元中

    assume cs:code data segment dw ,,,,,,, dd ,,,,,,, data ends code segment start: mov ax,data mov ds,a ...

  2. volley的post请求

    //volley发送post请 2 private void volleypost() { 3 String url = "http://apis.juhe.cn/idcard/index? ...

  3. 手机端适配iPhoneX

    iPhoneX取消了物理按键,改成底部小黑条,这一改动导致网页出现比较尴尬的屏幕适配问题.对于网页而言,顶部(刘海部位)的适配问题浏览器已经做了处理,所以我们只需要关注底部与小黑条的适配问题即可(即常 ...

  4. Android Studio 发布 APK

    打开发布设置窗口 打开Generate Signed APK...窗口,点击Create new... 打开Create New...窗口,创建一个Key,这个Key的相关信息一定要好好保存,因为以后 ...

  5. (转)silverlight应用程序中未处理的错误代码:2104 类别:InitializeError

        解决方案:第一步:默认网站--属性-----http头 第二步:点击mime类型: 第三步:点击新建: 第四步:输入扩展名以及类型: (1) 扩展名:.xaml MIME类型:applicat ...

  6. Java基础之—反射

    反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))   一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...

  7. hdu 1983(BFS+DFS) 怪盗Kid

    http://acm.hdu.edu.cn/showproblem.php?pid=1983 首先,题目要求出口和入口不能封闭,那么,只要把出口或入口的周围全给封闭了那盗贼肯定无法成功偷盗,出口或入口 ...

  8. BZOJ1001或洛谷4001 [BJOI2006]狼抓兔子

    BZOJ原题链接 洛谷原题链接 显然就是求最小割. 而对于一个平面图有结论,最大流=最小割=对偶图最短路. 所以这题可用最大流或是转换为对偶图求最短路,这里我是用的对偶图. 虽然理论上按上界算,这题\ ...

  9. BZOJ2730或洛谷3225 [HNOI2012]矿场搭建

    BZOJ原题链接 洛谷原题链接 显然在一个点双连通分量里,无论是哪一个挖煤点倒塌,其余挖煤点就可以互相到达,而对于一个点双连通分量来说,与外界的联系全看割点,所以我们先用\(tarjan\)求出点双连 ...

  10. nodejs buffer 内存泄漏问题

    摘自<Node.js 高级编程> var buffer = new Buffer("this is the content of my buffer"); var sm ...