gcc编译器优化给我们带来的麻烦???
gcc编译器优化给我们带来的麻烦???
今天看到一个很有趣的程序,如下:
1
2
3
4
5
6
7
8
9
|
int main() { const int a = 1; int *b = ( int *)&a; *b = 21; printf ( "%d, %d" , a, *b); return 0; } |
当我第一眼看到这个程序的时候,我想当然的认为输出结果是21, 21,但是我错了
一时很难理解,于是我又输出了它们的地址:
int main() { const int a = 1; int *b = ( int *)&a; *b = 21; printf ( "%d, %d" , a, *b); printf ( "\n%p, %p" , &a, &*b); return 0; } |
它们的地址是一样的,看到这里我更加的不解,于是我试着查看一下汇编代码。
int main() { const int a = 1; int *b = ( int *)&a; *b = 21; printf ( "%d" , a); return 0; } |
对应汇编代码如下:
这里得到的是at&t的汇编代码,与intel不同之处在于:
1,指令格式为:指令名称 元操作数 目的操作数
2,寄存器前加%
3,操作数前加$
4,0x4(%esp)为内存寻址,实际表示的是esp寄存器中的内容 + 4(如果不是很明白,望自行查找资料,本人知识有限)
我们首先看标号为1的行,对应c语句为const int a =1,这是把1放进地址为0x18(%esp)的地方,再来看标号2的地方,对应的printf语句,发现并没有引用地址为0x18(%esp)的地方的值,而是把1直接放到了0x4(%esp),然后输出。
所以个人认为,之所以会出现最开始的结果,是因为编译器给我们做了一些优化导致的。为了证明我的观点,我修改了程序:
int main() { int c = 1; const int a = c; int *b = ( int *)&a; *b = 21; printf ( "%d, %d" , a, *b); return 0; } |
输出结果为:
对应的汇编代码为:
在标号1处,我们可以确定a存放在0x14(%esp)的地方,在标号2处,对应的printf语句,此语句从右向左处理参数,2处理的是*b,3处理的是a,这时看到用的是地址,而不是直接用数值,同时看标号0处,我们是将c赋值1,再给a赋值时编译器用的是数值,并没有引用地址。
所以,个人猜测,编译器在这方面有一个优化功能:如果一个变量在定义时赋值常量,那么在引用它的时候,编译器会直接用该常量数值代替地址的引用来节省时间,但是也给我们带来了以外的麻烦。
这些都是个人的观点,希望各位指教!!!
gcc编译器优化给我们带来的麻烦???的更多相关文章
- 【转】C 编译器优化过程中的 Bug
C 编译器优化过程中的 Bug 一个朋友向我指出一个最近他们发现的 GCC 编译器优化过程(加上 -O3 选项)里的 bug,导致他们的产品出现非常诡异的行为.这使我想起以前见过的一个 GCC bug ...
- GCC 编译优化指南(转)
GCC 编译优化指南(转) http://www.jinbuguo.com/linux/optimize_guide.html 作者:金步国 版权声明 本文作者是一位开源理念的坚定支持者,所以本文虽然 ...
- GCC 编译优化指南
转自: http://www.jinbuguo.com/linux/optimize_guide.html GCC 编译优化指南 作者:金步国[www.jinbuguo.com] 版权声明 本文作者是 ...
- GCC编译优化指南【作者:金步国】
GCC编译优化指南[作者:金步国] GCC编译优化指南 作者:金步国 版权声明 本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布.任何人都可以自由使用.转载.复制和再分 ...
- GCC 编译优化指南【转】
转自:http://www.jinbuguo.com/linux/optimize_guide.html 版权声明 本文作者是一位开源理念的坚定支持者,所以本文虽然不是软件,但是遵照开源的精神发布. ...
- gcc编译器命令使用详解
1.gcc包含的c/c++编译器gcc,cc,c++,g++,gcc和cc是一样的,c++和g++是一样的,(没有看太明白前面这半句是什么意思:))一般c程序就用gcc编译,c++程序就用g++编译 ...
- 在CentOS 7.2下升级gcc编译器的版本
默认情况下,CentOS 7.2预装的gcc版本是4.8.x,通过执行命令 gcc -v 可以看到,一般情况下这个版本的编译器已经满足需要了,但是某些特殊的时候为了支持C++更高的特性,需要对gcc编 ...
- GCC编译器编译链接
在gcc编译器环境下,常见的文件扩展名的含义如下: .c:C源程序,经过预编译后的源程序也为.c文件,它可以通过-E参数输出. .h:头文件 .s:经过编译得到的汇编程序代码,它可以通过-S参数输出. ...
- Linux安装gcc编译器详解
本人使用的是CentOS 6.5 64位系统,由于在安装系统的时候并没有勾选安装gcc编译器,因此需要自行安装gcc编译器. 使用yum安装gcc 对于配备了yum的Linux发行版而言,安装gcc编 ...
随机推荐
- GitBook配置
GitBook 是一个通过 Git 和 Markdown 来撰写书籍的工具.生成格式有:JSON.ePub.PDF.Website ! ================================ ...
- [CLR via C#]1.1 将源代码编译成托管代码
原文:[CLR via C#]1.1 将源代码编译成托管代码 1. 公共语言运行时(Common Language Runtime,CLR)是一种可由多种编程语言使用的"运行时". ...
- SOA一些资料
SOA相关资料整理分享 2015-03-26 16:16 by 蘑菇先生, 693 阅读, 9 评论, 收藏, 编辑 昨@幸福框架同学问能否推荐SOA一些资料.想想之前看过不少资料文档,就整理分享下. ...
- Windows 注册和取消注册一个dll或者ocx
原文:Windows 注册和取消注册一个dll或者ocx 一.DLL是什么 DLL,是Dynamic Link Library 的缩写形式,中文名称为动态链接库. DLL是 ...
- Write the code.Change the world.---WWDC2014
- OC第四课
主要内容:NSString.NSArray.NSNumber 一.苹果公司的帮助文档(API) 学会查看API对于后续的编程有很好的帮助 进入方法: Xcode ->Help -> Doc ...
- C# .NET ASP.NET 其中关系你了解多少
有些人一直在做这方面..但突然有人来问你这些问题..估计有很多答不上来. 1..NET是一个平台,一个抽象的平台的概念. .NET平台其本身实现的方式其实还是库,抽象层面上来看是一个平台. 个人理解. ...
- 《C语言及程序设计初步》网络课程主页
题记 CSDN要开在线教育频道,向我发出邀请,看能否开些课程. 我近日一直在关注着翻转课堂,试图在传统课堂中引入新的元素,这须要资源建设的积累.没有时间表的工作,非常难把握. 为CSDN做在线课程,为 ...
- 日志分析工具-ApexSQL介绍
原文:日志分析工具-ApexSQL介绍 使用场景:业务数据异常变化,通过代码分析不出来的时候,迫不得已需要通过日志来分析 下载地址:http://www.apexsql.com/Download.as ...
- jQuery在线选座订座(影院篇)
原文:jQuery在线选座订座(影院篇) 我们在线购票时(如电影票.车票等)可以自己选座.开发者会在页面上列出座次席位,用户可以一目了然的看到可以选择的座位及支付.本文以电影院购票为例,为您展示如何选 ...