GCC几个选项学习
来源:互联网 发布:网络语奥利奥什么意思 编辑:程序博客网 时间:2024/06/10 22:27
最近研究了一把GCC的选项,比较有意思,选些出来,学习学习。编译器作为程序员的重要工具,GCC作为编译器中应用最广泛的,无不处处体现出贴心的设计和功能支持。
Table of Contents
- 1 -dumpmachine
- 2 -xc
- 3 -dM
- 4 -print-file-name=include
- 5 -isystem DIR
- 6 -nostdinc/-nostdinc++
- 7 -Wp/-Wa/-Wl
- 8 -EL/-EB
- 9 -DMACRO/-UMACRO
- 10 -G num
- 11 -msym32/-mnosym32
- 12 -fdelete-null-pointer-checks/-fno-delete-null-pointer-checks
- 13 -mcheck-zero-division/-mno-check-zero-division
- 14 -mabicalls/-mno-abicalls
- 15 -mbranch-likely/-mno-branch-likely
- 16 -fstack-protector
- 17 -fstrict-overflow
- 18 -fconserve-stack
- 19 参考
1 -dumpmachine
给出当前使用GCC的信息,在erlv的Debian AMD64上,结果如下。
关于GCC的这些字段是什么意思,请参考这篇博文:
$ gcc -dumpmachinex86_64-linux-gnu
2 -xc
其实,-xc和 “-x c”等同。
x用于指定输入的程序的语言,如果使用该选项,GCC就不再根据文件的后缀名判断语言类型。
from "info gcc":
Overall Options
-c -S -E -o file -combine -pipe -pass-exit-codes -x language
-v -### --help[=class[,...]] --target-help --version
-wrapper@file
3 -dM
不做实际的预处理,仅仅列出所有#define的宏,这些宏大部分与体系结构和GNU相关,或来自所包含的头文件。
#程序输出太长,这里就不列出了$gcc -E -dM hello.c
另外,还有一些-dCHARS的组合选项:
- -dD:和-dM类似,不过仅仅包含头文件中定义的宏,不会输出预处理器中默认定义的宏,另外会将源程序代码也预处理输出。
- -dN:和-dD类似,但仅输出定义的宏的名称,不输出宏的值。
- -dI:给出#include的头文件,预计预处理的结果
- -dU:和-dD类似,但仅仅输出那些在源码中需要展开的,或者其定义会被测试到的宏。
4 -print-file-name=include
打印GCC默认搜索include头文件的路径
$ gcc -print-file-name=include/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.6.1/include
5 -isystem DIR
将DIR路径作为头文件搜索路径之一。搜索顺序: -I指定的文件夹 =》 -isystem指定的文件夹 =》 标准系统头文件夹。
6 -nostdinc/-nostdinc++
不要搜索标准系统头文件目录,仅搜索-I指定的路径。
7 -Wp/-Wa/-Wl
这三个分别用来指定传递给 预处理起、汇编器和链接器的参数。
- -Wp,option 等价于 -Xpreprocessor option
- -Wa,option 等价于 -Xassembler option
- -Wl,option 等价于 -Xlinker option
8 -EL/-EB
为小尾端/大尾端系统编译代码。默认是小尾端
9 -DMACRO/-UMACRO
定义宏MACRO/撤销对宏MACRO的定义
10 -G num
将全局和静态对象的大小分割成小于num字节的数据放入bss端的小数据中,而非正常数据中。
默认的num的值为8.
由于MIPS在从符号得到地址时,需要先取出高16位,再取出低16位,做拼接得到最终地址,所以就需要两次访存操作。
当程序中大量使用静态和全局数据时,这种方式就会让程序变慢。
于是就有了利用GP寄存器进行优化的方法,即采用和GP寄存器做相对偏移的方式访存,以便降低访存次数。
关键问题是编译器和汇编器需要在编译时刻确定哪些变量可以使用GP寄存器访问。
通常的做法是让大小小于一定值的变量通过GP寄存器访问。
若num为 0表示将这一优化关闭。
11 -msym32/-mnosym32
不管采取何种ABI,都假设/不假设所有符号都是32位的值。
这一选项配合-mabi=64 和-mno-abicall时非常有用,因为可以通过假设都是32位数据生成更小巧更快的符号地址
12 -fdelete-null-pointer-checks/-fno-delete-null-pointer-checks
delete-null-pointer-checks是一种优化手段,通过全局的数据流分析来识别和删除所有对空指针的检测操作。
编译器假定对空指针的解引用会造成程序终止。但因为有些环境下,这一结论并不一定成立,而O2,O3和Os时会开启此优化。
因此GCC增加了选项-fno-delete-null-pointer-checks
13 -mcheck-zero-division/-mno-check-zero-division
当整数除0操作时,陷入/不陷入
14 -mabicalls/-mno-abicalls
生成/不生成适SVR4形式的动态对象代码,默认生成。
15 -mbranch-likely/-mno-branch-likely
使用/使用 branch likely 指令,不管所指定体系结构默认是否支持。
GCC默认会为支持branch likely指令的体系结构生成branch likely指令。
引入这类指令,是为了引入一种很大可能会发生跳转的指令,这样编译器就能充分的利用MIPS中的delay slot。
16 -fstack-protector
为可能的缓冲区溢出生成额外的检测代码。
17 -fstrict-overflow
允许编译器使用严格的有符号溢出规则。
18 -fconserve-stack
尽量减小对栈的使用。
19 参考
- http://gcc.gnu.org/ml/gcc-help/2006-10/msg00191.html
- See MIPS Run Linux, 2ed, by Dominic Sweetman, Page 273
- GCC man pages
6 thoughts on “GCC几个选项学习”
- GCC几个选项学习
- gcc 几个常用选项
- GCC的几个常用选项
- gcc编译选项学习
- GCC中常用的几个选项
- GCC的几个重要选项解释
- GCC的几个重要选项解释
- linux中gcc命令选项的常用几个选项
- 嵌入式学习笔记 : GCC选项
- GCC编译警告选项的学习
- Gcc选项
- GCC 选项
- GCC 选项
- gcc 选项
- gcc选项
- gcc选项
- gcc 选项
- 【gcc】gcc常用选项
- 通过浏览器直接打开iOS/Android App 应用程序 - Cundong's log - 开源中国社区
- Java解惑之找零时刻
- 聚类算法总结
- 事务—EJB事务(CMT)
- 用伪类清除浮动
- GCC几个选项学习
- 基金定投收益分析
- android请求https(二)使用HttpClient 请求https
- JS 之 数据类型转换
- 关于刷标辅助软件的制作
- 什么是框架
- 华为机试—竞赛 西安2016届校园招聘练习(A卷)
- Android数据存车和访问
- Asp.net mvc 期末试题及答案
llvm said on 2011年7月12日 at 下午11:30:
想请教一下,如果想建立一门新的语言,或者改进现有语言(比如erlang,python),使用llvm,gcc,open64哪个作为后端较好呢?它们各自的发展潜力,改造成本和工具支持如何?
erlv said on 2011年7月13日 at 下午1:31:
LLVM、Open64都使用GCC的词法语法分析部分,另外LLVM也正在开发独立的词法语法分析前端Clang。 这几个编译器目前支持最好的语言是C语言,其次是C++。GCC还支持Java、Ada、Fortran等语言。据我所知,目前这三者中,LLVM有个python支持项目 unladden swallow(http://code.google.com/p/unladen-swallow/),GCC有python(http://gcc.gnu.org/wiki/PythonFrontEnd)。Erlang方面,GCC还没有支持,LLVM请参考这个(http://lists.cs.uiuc.edu/pipermail/llvmdev/2008-July/016088.html)。
发展潜力方面,LLVM应该在C、C++语言上很有潜力,不过其他语言就不一定了。GCC的话,仍然会保持主流地位,因为有一堆GNU的软件在使用。
改造成本方面,LLVM因为代码相对清晰简单,改造成本较低,GCC高很多。工具的话,貌似这两个编译器都不是简单的使用lex和yacc做的词法语言分析,如果能打算做新语言的话,估计这部分得自己写,只要能最后得到GCC的中间表示,应该在LLVM、Open64上都能使用,因为这三者都有GCC前端的接口在。
llvm said on 2011年7月13日 at 下午5:38:
虽然llvm有gcc的接口,但是改成gcc的中间表示后,会不会失去llvm的优势呢?
llvm said on 2011年7月13日 at 下午6:04:
我比较倾向于选择llvm,感觉它周边的配套工具比较丰富,中间语言也简单一点,主要是出于学习目的想做一点新语言的优化。不过不太了解编译工具几大阵营的状况…呵呵。c和c 的编译,感觉继续挖掘潜力的难度较大
erlv said on 2011年7月14日 at 上午9:09:
1,C/C++语言的编译优化基本上可挖的点不多了,除非是有新的体系结构
2, LLVM的确程序会清晰、简单很多。不过可能存在有些优化没有GCC、Open64分析的更全面,优化效果更好的问题,所以你可能需要权衡一下。
3, 目前,因为LLVM的确有不少周边项目,比如为LLVM增加各种语言前端,但这些前端估计都不够成熟,得看你是基于什么语言来改。
4,至于改成GCC中间表示后会不会失去LLVM的优势,这个得看你是否用到了一些只有LLVM才特有的中间表示特性,如果有估计会有影响,如果没有的话,个人觉得没有太大差别。这个我也不太了解,直觉而已:)