“-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. kalman滤波(一)---对各参数的理解

    一.引言 1.卡尔曼滤波中的真实值,测量值,预测值,估计值怎么区分?他的5条公式是其核心内容,结合现代的计算机,其实卡尔曼的程序相当的简单,只要你理解了他的那5条公式. 用一个简单的小例子:假设我们要 ...

  2. os模块。笔记

    os 模块提供了很多允许你的程序与操作系统直接交互的功能 得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目录名:os.listdir()  ...

  3. Git 安装和使用教程(更加详细)

    转载至:https://www.cnblogs.com/smuxiaolei/p/7484678.html#undefined Git 安装和使用教程 git 提交 全部文件 git add .  g ...

  4. CSS学习总结1:CSS样式

    1.CSS背景 属性 background-color:为元素设置背景色,值可以是任何合法的颜色值.实例:p {background-color: gray;} background-image:为元 ...

  5. Liunx 硬盘分区

    1)什么要进行硬盘分区:a) 更容易管理和控制系统,因为相关的文件和目录都放在一个分区中.b) 系统效率更高.c) 可以限制用户使用硬盘的份额(磁盘空间的大小).d) 更容易备份和恢复. 2)硬盘的逻 ...

  6. springboot中controller的使用

    一.知识点 1 @Controller 处理http请求(不推荐使用) 2 @RestController spring4之后新加的注解,原来返回json需要@ResponseBody配合@Contr ...

  7. Unix和Windows文件格式转化

    可能的原因有: 1)执行权限的问题 解决方法: chmod +x ***.py 2)python版本的问题 解决方法:在执行时或者在py文件中选择好对应的Python的版本 3)python文件格式的 ...

  8. String、StringBuffer、StringBuilder和StringTokenizer的区别

    1)String.StringBuffer.StringBuilder都用于字符串操作,其中,String是不可变类,即String对象一旦被创建,其值不能被修改,而StringBuffer和Stri ...

  9. [Robot Framework] 通过Robot Remote Server调用White Library测试WPF开发的桌面产品

    参考 : https://github.com/jatalahd/WhiteRobotLibrary 通过此源代码编译WhiteRobotLibrary.dll,然后把高亮标记的这5个dll全部拷贝到 ...

  10. where

    (二)WHERE //where不单独使用,与match,optional match,start,with搭配 where 与match,optional match 一起用,表示约束 where ...