“-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. div指令和mul指令

    div是除法指令,使用div做除法时需要注意: 1)除数:有8位和16位两种,在一个寄存器或者内存单元中 2)被除数:默认存放在AX或DX和AX中.如果除数为8位,被除数则为16位,默认在AX中存放: ...

  2. setTimeout设置为0的意义

    今天再看 Promise 代码时,有个地方用到了setTimeOut函数,但是第2个参数设为0,顿时懵逼了,这是啥意思? function resolve(newValue) { value = ne ...

  3. mysql5.7 新增的json字段类型

    一.我们先创建一个表,准备点数据 CREATE TABLE `json_test` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'I ...

  4. Cmd下修改文件访问控制权限

    保证自己的磁盘分区格式是NTFS.FAT32是不行的. 一.Cacls.exe命令的使用 这是一个在Windows 2000/XP/Server 2003操作系统下都可以使用的命令,作用是显示或者修改 ...

  5. NuGet打包,IIS自动发布

    NuGet学习笔记(1)——初识NuGet及快速安装使用 https://kb.cnblogs.com/page/143190/ NuGet学习笔记(2)——使用图形化界面打包自己的类库 https: ...

  6. [z]根据awr报告查看最慢的sql语句

    http://blog.itpub.net/12679300/viewspace-2125679/ 当系统运行了一段时间后,系统基本也趋于稳定了,SQL调优也变了DBA的一个主要的工作内容,很多时候都 ...

  7. 11.1JS笔记

    1.js的数据类型分为基本和引用,基本(string.undefined.null.number,boolean),引用(object-->array.function.json等) 2.基本数 ...

  8. 11.Mysql视图

    11.视图11.1 什么是视图 视图view是一张虚拟表,它不存储数据,数据仍在表里,视图由一条查询表的select语句创建,视图只存储select语句. 可以将复杂的查询语句封装成视图,用户可以从视 ...

  9. Github上Markdown基本语法

    基础写作和语法格式 本篇文章的内容来源于Github的基础写作帮助.如果在观看时有什么问题,可以直接查阅源文件.另外需要说明的是Git对Markdown的支持增加了一些扩展功能,因此在Git上可以渲染 ...

  10. hdu 2119(简单二分图) Matrix

    http://acm.hdu.edu.cn/showproblem.php?pid=2119 一个由0和1构成的矩阵,每次选取一行或者一列将其中的1变成0,求最小删除次数 简单的二分图应用,矩阵的横坐 ...