GCC常用选项&使用详解

通常所说的GCC是GUN Compiler Collection的简称,除了编译程序之外,它还含其他相关工<wbr>具,所以它能把易于人类使用的高级语言编写的源代码构建成计算机能<wbr>够直接执行的二进制代码。GCC是Linux平台下最常用的编译程序,它是Linux平<wbr>台编译器的事实标准。同时,在Linux平台下的嵌入式开发领域<wbr>,GCC也是用得最普遍的一种编译器。GCC之所以被广泛采用,是因为它能支持各种不同的<wbr>目标体系结构。例如,它既支持基于宿主的开发(简单讲就是要为某平<wbr>台编译程序,就在该平台上编译),也支持交叉编译(即在A平台上编译的程序是供平台B使<wbr>用的)。目前,GCC支持的体系结构有四十余种,常见的有X86系<wbr>列、Arm、 PowerPC等。同时,GCC还能运行在不同的操作系统上<wbr>,如Linux、Solaris、Windows等。<br><br> 除了上面讲的之外,GCC除了支持C语言外,还支持多种其他语言<wbr>,例如C++、Ada、Java、Objective-C<wbr>、FORTRAN、Pascal等。<br><br> 本系列文章中,我们不仅介绍GCC的基本功能,还涉及到一些诸如优<wbr>化之类的高级功能。另外,我们还考察GCC的一些映像操作工具<wbr>,如size和objcopy等,这将在后续的文章中加以介绍。<br><br> 二、程序的编译过程<br><br> 对于GUN编译器来说,程序的编译要经历预处理、编译、汇编<wbr>、连接四个阶段,如下图所示:<br><br><br><br> 从功能上分,预处理、编译、汇编是三个不同的阶段<wbr>,但GCC的实际操作上,它可以把这三个步骤合并为一个步骤来执行<wbr>。下面我们以C语言为例来谈一下不同阶段的输入和输出情况。<br><br> 在预处理阶段,输入的是C语言的源文件,通常为*.c。它们通常带有.h之类头文件的包含文件。这个阶段主要处理源文件中的#ifdef、 #i nclude和#define命令。该阶段会生成一个中间文件<wbr>*.i,但实际工作中通常不用专门生成这种文件,因为基本上用不到<wbr>;若非要生成这种文件不可,可以利用下面的示例命令:<br><br> gcc -E test.c -o test.i<br><br> 在编译阶段,输入的是中间文件*.i,编译后生成汇编语言文件*<wbr>.s 。这个阶段对应的GCC命令如下所示:<br><br> GCC -S test.i -o test.s<br><br> 在汇编阶段,将输入的汇编文件*.s转换成机器语言*.o<wbr>。这个阶段对应的GCC命令如下所示:<br><br> GCC -c test.s -o test.o<br><br> 最后,在连接阶段将输入的机器代码文件*.s(与其它的机器代码文<wbr>件和库文件)汇集成一个可执行的二进制代码文件。这一步骤<wbr>,可以利用下面的示例命令完成:<br><br> GCC test.o -o test<br><br> 上面介绍了GCC编译过程的四个阶段以及相应的命令<wbr>。下面我们进一步介绍常用的GCC的模式。<br><br> 三、GCC常用模式<br><br> 这里介绍GCC追常用的两种模式:编译模式和编译连接模式<wbr>。下面以一个例子来说明各种模式的使用方法。为简单起见,假设我们全部的源代码都在一个文件test.c中,要想把这个源文件直接编译成可执行程序,可以使用以下命令:<br><br> $ GCC -o test<br><br> 这里test.c是源文件,生成的可执行代码存放在一个名为test 的文件中(该文件是机器代码并且可执行)。-o 是生成可执行文件的输出选项。如果我们只想让源文件生成目标文件<wbr>(给文件虽然也是机器代码但不可执行),可以使用标记-c ,详细命令如下所示:<br><br> $ GCC -c test.c<br><br> 默认情况下,生成的目标文件被命名为test.o,但我们也可以为输出文件指定名称,如下所示:<br><br> $ GCC -c test.c -o<br><br> 上面这条命令将编译后的目标文件命名为mytest.o,而不是默认的test.o。<br><br> 迄今为止,我们谈论的程序仅涉及到一个源文件;现实中<wbr>,一个程序的源代码通常包含在多个源文件之中,这该怎么办<wbr>?没关系,即使这样,用GCC处理起来也并不复杂,见下例:<br><br> $ GCC -o test first.c second.c third.c<br><br> 需要注意的是,要生成可执行程序时,一个程序无论有有一个源文件还<wbr>是多个源文件,所有被编译和连接的源文件中必须有且仅有一个mai <wbr>n函数,因为main 函数是该程序的入口点(换句话说,当系统调用该程序时<wbr>,首先将控制权授予程序的main函数)。但如果仅仅是把源文件编<wbr>译成目标文件的时候,因为不会进行连接,所以main函数不是必需的。<br><br> 四、常用选项<br><br> 许多情况下,头文件和源文件会单独存放在不同的目录中。例如<wbr>,假设存放源文件的子目录名为./src,而包含文件则放在层次的<wbr>其他目录下,如./inc。当我们在./src 目录下进行编译工作时,如何告诉GCC到哪里找头文件呢<wbr>?方法如下所示:<br><br> $ gcc test.c –I../inc -o test<br><br> 上面的命令告诉GCC包含文件存放在./inc 目录下,在当前目录的上一级。如果在编译时需要的包含文件存放在多<wbr>个目录下,可以使用多个-I 来指定各个目录:<br><br> $ gcc test.c –I../inc –I../../inc2 -o test<br><br> 这里指出了另一个包含子目录inc2,较之前目录它还要在再上两级<wbr>才能找到。<br><br> 另外,我们还可以在编译命令行中定义符号常量。为此<wbr>,我们可以简单的在命令行中使用-D选项即可,如下例所示:<br><br> $ gcc -DTEST_CONFIGURATION test.c -o test<br><br> 上面的命令与在源文件中加入下列命令是等效的:<br><br> #define TEST_CONFIGURATION<br><br> 在编译命令行中定义符号常量的好处是,不必修改源文件就能改变由符<wbr>号常量控制的行为。<br><br> 五、警告功能<br><br> 当GCC 在编译过程中检查出错误的话,它就会中止编译;但检测到警告时却能<wbr>继续编译生成可执行程序,因为警告只是针对程序结构的诊断信息<wbr>,它不能说明程序一定有错误,而是存在风险,或者可能存在错误。虽然GCC提供了非常丰富的<wbr>警告,但前提是你已经启用了它们,否则它不会报告这些检测到的警告<wbr>。<br><br> 在众多的警告选项之中,最常用的就是-Wall选项<wbr>。该选项能发现程序中一系列的常见错误警告,该选项用法举例如下:<br><br> $ gcc -Wall test.c -o test<br><br> 该选项相当于同时使用了下列所有的选项:<br><br> ◆unused-function:遇到仅声明过但尚未定义的静态<wbr>函数时发出警告。<br><br> ◆unused-label:遇到声明过但不使用的标号的警告。<br><br> ◆unused-parameter:从未用过的函数参数的警告。<br><br> ◆unused-variable:在本地声明但从未用过的变量的<wbr>警告。<br><br> ◆unused-value:仅计算但从未用过的值得警告。<br><br> ◆Format:检查对printf和scanf等函数的调用<wbr>,确认各个参数类型和格式串中的一致。<br><br> ◆implicit-int:警告没有规定类型的声明。<br><br> ◆implicit-function-:在函数在未经声明就使用<wbr>时给予警告。<br><br> ◆char-subscripts:警告把char类型作为数组下<wbr>标。这是常见错误,程序员经常忘记在某些机器上char有符号。<br><br> ◆missing-braces:聚合初始化两边缺少大括号。<br><br> ◆Parentheses:在某些情况下如果忽略了括号<wbr>,编译器就发出警告。<br><br> ◆return-type:如果函数定义了返回类型<wbr>,而默认类型是int型,编译器就发出警告。同时警告那些不带返回<wbr>值的 return语句,如果他们所属的函数并非void类型。<br><br> ◆sequence-point:出现可疑的代码元素时<wbr>,发出报警。<br><br> ◆Switch:如果某条switch语句的参数属于枚举类型<wbr>,但是没有对应的case语句使用枚举元素,编译器就发出警告<wbr>(在switch语句中使用default分支能够防止这个警告<wbr>)。超出枚举范围的case语句同样会导致这个警告。<br><br> ◆strict-aliasing:对变量别名进行最严格的检查。<br><br> ◆unknown-pragmas:使用了不允许的<wbr>#pragma。<br><br> ◆Uninitialized:在初始化之前就使用自动变量。<br><br> 需要注意的是,各警告选项既然能使之生效,当然也能使之关闭 <wbr>。比如假设我们想要使用-Wall来启用个选项,同时又要关闭un<wbr>used警告,利益通过下面的命令来达到目的:<br><br> $ gcc -Wall -Wno-unused test.c -o test<br><br> 下面是使用-Wall选项的时候没有生效的一些警告项:<br><br> ◆cast-align:一旦某个指针类型强制转换时<wbr>,会导致目标所需的地址对齐边界扩展,编译器就发出警告。例如<wbr>,某些机器上只能在2或4字节边界上访问整数,如果在这种机型上把<wbr>char *强制转换成int *类型, 编译器就发出警告。<br><br> ◆sign-compare:将有符号类型和无符号类型数据进行比<wbr>较时发出警告。<br><br> ◆missing-prototypes :如果没有预先声明函数原形就定义了全局函数,编译器就发出警告<wbr>。即使函数定义自身提供了函数原形也会产生这个警告<wbr>。这样做的目的是检查没有在头文件中声明的全局函数。<br><br> ◆Packed:当结构体带有packed属性但实际并没有出现紧<wbr>缩式给出警告。<br><br> ◆Padded:如果结构体通过充填进行对齐则给出警告。<br><br> ◆unreachable-code:如果发现从未执行的代码时给<wbr>出警告。<br><br> ◆Inline:如果某函数不能内嵌(inline)<wbr>,无论是声明为inline或者是指定了-finline<wbr>-functions 选项,编译器都将发出警告。<br><br> ◆disabled-optimization:当需要太长时间或<wbr>过多资源而导致不能完成某项优化时给出警告。<br><br> 上面是使用-Wall选项时没有生效,但又比较常用的一些警告选项<wbr>。本文中要介绍的最后一个常用警告选项是-Werror<wbr>。使用该选项后,GCC发现可疑之处时不会简单的发出警告就算完事<wbr>,而是将警告作为一个错误而中断编译过程。该选项在希望得到高质量<wbr>代码时非常有用。<br><br> 六、小结<br><br> 本文介绍了GCC的基本编译过程和编译模式,并详细阐述了GCC的<wbr>一些常用选项以及警告功能。这些是在利用GCC进行应用编程时最基<wbr>本也最常用的一些内容,我们会在后续文章中继续介绍GCC的调试和<wbr>优化技术。<br> 该命令将同时编译三个源文件,即first.c、second.c和 third.c,然后将它们连接成一个可执行程序,名为test。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

附录:

[参数详解]
-x language filename
   设定文件所使用的语言,使后缀名无效,对以后的多个有效.也就是根
   据约定c语言的后缀名称是.c的,而c++的后缀名是.c或者.cpp,如果
   你很个性,决定你的c代码文件的后缀名是.pig 哈哈,那你就要用这
   个参数,这个参数对他后面的文件名都起作用,除非到了下一个参数
   的使用。
   可以使用的参数吗有下面的这些
     `c, `objective-c, `c-header, `c++, `cpp-output,
     `assembler, and `assembler-with-cpp.
   看到英文,应该可以理解的。
   例子用法:
   gcc -x c hello.pig
  
-x none filename
  关掉上一个选项,也就是让gcc根据文件名后缀,自动识别文件类型
  例子用法:
  gcc -x c hello.pig -x none hello2.c
  
-c
  只激活预处理,编译,和汇编,也就是他只把程序做成obj文件
  例子用法:
  gcc -c hello.c
  他将生成.o的obj文件

-s
  只激活预处理和编译,就是指把文件编译成为汇编代码。
  例子用法
  gcc -s hello.c
  他将生成.s的汇编代码,你可以用文本编辑器察看

-e
  只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里
  面.
  例子用法:
  gcc -e hello.c > pianoapan.txt
  gcc -e hello.c | more
  慢慢看吧,一个hello word 也要与处理成800行的代码

-o
  制定目标名称,缺省的时候,gcc 编译出来的文件是a.out,很难听,如果
  你和我有同感,改掉它,哈哈
  例子用法
  gcc -o hello.exe hello.c (哦,windows用习惯了)
  gcc -o hello.asm -s hello.c

-pipe
  使用管道代替编译中临时文件,在使用非gnu汇编工具的时候,可能有些问
  题
  gcc -pipe -o hello.exe hello.c

-ansi
  关闭gnu c中与ansi c不兼容的特性,激活ansi c的专有特性(包括禁止一
  些asm inline typeof关键字,以及unix,vax等预处理宏,

-fno-asm
  此选项实现ansi选项的功能的一部分,它禁止将asm,inline和typeof用作
  关键字。
    
-fno-strict-prototype
  只对g++起作用,使用这个选项,g++将对不带参数的函数,都认为是没有显式
  的对参数的个数和类型说明,而不是没有参数.
  而gcc无论是否使用这个参数,都将对没有带参数的函数,认为城没有显式说
  明的类型
  
-fthis-is-varialble
  就是向传统c++看齐,可以使用this当一般变量使用.
  
-fcond-mismatch
  允许条件表达式的第二和第三参数类型不匹配,表达式的值将为void类型
  
-funsigned-char
-fno-signed-char
-fsigned-char
-fno-unsigned-char
  这四个参数是对char类型进行设置,决定将char类型设置成unsigned char(前
  两个参数)或者 signed char(后两个参数)
  
-include file
  包含某个代码,简单来说,就是便以某个文件,需要另一个文件的时候,就可以
  用它设定,功能就相当于在代码中使用#include<filename>
  例子用法:
  gcc hello.c -include /root/pianopan.h
  
-imacros file
  将file文件的宏,扩展到gcc/g++的输入文件,宏定义本身并不出现在输入文件
  中
  
-dmacro
  相当于c语言中的#define macro
  
-dmacro=defn
  相当于c语言中的#define macro=defn
  
-umacro
  相当于c语言中的#undef macro

-undef
  取消对任何非标准宏的定义
  
-idir
  在你是用#include"file"的时候,gcc/g++会先在当前目录查找你所制定的头
  文件,如果没有找到,他回到缺省的头文件目录找,如果使用-i制定了目录,他
  回先在你所制定的目录查找,然后再按常规的顺序去找.
  对于#include<file>,gcc/g++会到-i制定的目录查找,查找不到,然后将到系
  统的缺省的头文件目录查找
  
-i-
  就是取消前一个参数的功能,所以一般在-idir之后使用
  
-idirafter dir
  在-i的目录里面查找失败,讲到这个目录里面查找.
  
-iprefix prefix
-iwithprefix dir
  一般一起使用,当-i的目录查找失败,会到prefix+dir下查找
  
-nostdinc
  使编译器不再系统缺省的头文件目录里面找头文件,一般和-i联合使用,明确
  限定头文件的位置
  
-nostdin c++
  规定不在g++指定的标准路经中搜索,但仍在其他路径中搜索,.此选项在创建
  libg++库使用
  
-c
  在预处理的时候,不删除注释信息,一般和-e使用,有时候分析程序,用这个很
  方便的
  
-m
  生成文件关联的信息。包含目标文件所依赖的所有源代码
  你可以用gcc -m hello.c来测试一下,很简单。
  
-mm
  和上面的那个一样,但是它将忽略由#include<file>造成的依赖关系。
  
-md
  和-m相同,但是输出将导入到.d的文件里面
  
-mmd
  和-mm相同,但是输出将导入到.d的文件里面
  
-wa,option
  此选项传递option给汇编程序;如果option中间有逗号,就将option分成多个选
  项,然后传递给会汇编程序
  
-wl.option
  此选项传递option给连接程序;如果option中间有逗号,就将option分成多个选
  项,然后传递给会连接程序.
  

-llibrary
  制定编译的时候使用的库
  例子用法
  gcc -lcurses hello.c
  使用ncurses库编译程序
  
-ldir
  制定编译的时候,搜索库的路径。比如你自己的库,可以用它制定目录,不然
  编译器将只在标准库的目录找。这个dir就是目录的名称。
  
-o0
-o1
-o2
-o3
  编译器的优化选项的4个级别,-o0表示没有优化,-o1为缺省值,-o3优化级别最
  高  
  
-g
  只是编译器,在编译的时候,产生条是信息。
  
-gstabs
  此选项以stabs格式声称调试信息,但是不包括gdb调试信息.
  
-gstabs+
  此选项以stabs格式声称调试信息,并且包含仅供gdb使用的额外调试信息.
  
-ggdb
  此选项将尽可能的生成gdb的可以使用的调试信息.


通常所说的GCC是GUN Compiler Collection的简称,除了编译程序之外,它还含其他相关工<wbr>具,所以它能把易于人类使用的高级语言编写的源代码构建成计算机能<wbr>够直接执行的二进制代码。GCC是Linux平台下最常用的编译程序,它是Linux平<wbr>台编译器的事实标准。同时,在Linux平台下的嵌入式开发领域<wbr>,GCC也是用得最普遍的一种编译器。GCC之所以被广泛采用,是因为它能支持各种不同的<wbr>目标体系结构。例如,它既支持基于宿主的开发(简单讲就是要为某平<wbr>台编译程序,就在该平台上编译),也支持交叉编译(即在A平台上编译的程序是供平台B使<wbr>用的)。目前,GCC支持的体系结构有四十余种,常见的有X86系<wbr>列、Arm、 PowerPC等。同时,GCC还能运行在不同的操作系统上<wbr>,如Linux、Solaris、Windows等。<br><br> 除了上面讲的之外,GCC除了支持C语言外,还支持多种其他语言<wbr>,例如C++、Ada、Java、Objective-C<wbr>、FORTRAN、Pascal等。<br><br> 本系列文章中,我们不仅介绍GCC的基本功能,还涉及到一些诸如优<wbr>化之类的高级功能。另外,我们还考察GCC的一些映像操作工具<wbr>,如size和objcopy等,这将在后续的文章中加以介绍。<br><br> 二、程序的编译过程<br><br> 对于GUN编译器来说,程序的编译要经历预处理、编译、汇编<wbr>、连接四个阶段,如下图所示:<br><br><br><br> 从功能上分,预处理、编译、汇编是三个不同的阶段<wbr>,但GCC的实际操作上,它可以把这三个步骤合并为一个步骤来执行<wbr>。下面我们以C语言为例来谈一下不同阶段的输入和输出情况。<br><br> 在预处理阶段,输入的是C语言的源文件,通常为*.c。它们通常带有.h之类头文件的包含文件。这个阶段主要处理源文件中的#ifdef、 #i nclude和#define命令。该阶段会生成一个中间文件<wbr>*.i,但实际工作中通常不用专门生成这种文件,因为基本上用不到<wbr>;若非要生成这种文件不可,可以利用下面的示例命令:<br><br> gcc -E test.c -o test.i<br><br> 在编译阶段,输入的是中间文件*.i,编译后生成汇编语言文件*<wbr>.s 。这个阶段对应的GCC命令如下所示:<br><br> GCC -S test.i -o test.s<br><br> 在汇编阶段,将输入的汇编文件*.s转换成机器语言*.o<wbr>。这个阶段对应的GCC命令如下所示:<br><br> GCC -c test.s -o test.o<br><br> 最后,在连接阶段将输入的机器代码文件*.s(与其它的机器代码文<wbr>件和库文件)汇集成一个可执行的二进制代码文件。这一步骤<wbr>,可以利用下面的示例命令完成:<br><br> GCC test.o -o test<br><br> 上面介绍了GCC编译过程的四个阶段以及相应的命令<wbr>。下面我们进一步介绍常用的GCC的模式。<br><br> 三、GCC常用模式<br><br> 这里介绍GCC追常用的两种模式:编译模式和编译连接模式<wbr>。下面以一个例子来说明各种模式的使用方法。为简单起见,假设我们全部的源代码都在一个文件test.c中,要想把这个源文件直接编译成可执行程序,可以使用以下命令:<br><br> $ GCC -o test<br><br> 这里test.c是源文件,生成的可执行代码存放在一个名为test 的文件中(该文件是机器代码并且可执行)。-o 是生成可执行文件的输出选项。如果我们只想让源文件生成目标文件<wbr>(给文件虽然也是机器代码但不可执行),可以使用标记-c ,详细命令如下所示:<br><br> $ GCC -c test.c<br><br> 默认情况下,生成的目标文件被命名为test.o,但我们也可以为输出文件指定名称,如下所示:<br><br> $ GCC -c test.c -o<br><br> 上面这条命令将编译后的目标文件命名为mytest.o,而不是默认的test.o。<br><br> 迄今为止,我们谈论的程序仅涉及到一个源文件;现实中<wbr>,一个程序的源代码通常包含在多个源文件之中,这该怎么办<wbr>?没关系,即使这样,用GCC处理起来也并不复杂,见下例:<br><br> $ GCC -o test first.c second.c third.c<br><br> 需要注意的是,要生成可执行程序时,一个程序无论有有一个源文件还<wbr>是多个源文件,所有被编译和连接的源文件中必须有且仅有一个mai <wbr>n函数,因为main 函数是该程序的入口点(换句话说,当系统调用该程序时<wbr>,首先将控制权授予程序的main函数)。但如果仅仅是把源文件编<wbr>译成目标文件的时候,因为不会进行连接,所以main函数不是必需的。<br><br> 四、常用选项<br><br> 许多情况下,头文件和源文件会单独存放在不同的目录中。例如<wbr>,假设存放源文件的子目录名为./src,而包含文件则放在层次的<wbr>其他目录下,如./inc。当我们在./src 目录下进行编译工作时,如何告诉GCC到哪里找头文件呢<wbr>?方法如下所示:<br><br> $ gcc test.c –I../inc -o test<br><br> 上面的命令告诉GCC包含文件存放在./inc 目录下,在当前目录的上一级。如果在编译时需要的包含文件存放在多<wbr>个目录下,可以使用多个-I 来指定各个目录:<br><br> $ gcc test.c –I../inc –I../../inc2 -o test<br><br> 这里指出了另一个包含子目录inc2,较之前目录它还要在再上两级<wbr>才能找到。<br><br> 另外,我们还可以在编译命令行中定义符号常量。为此<wbr>,我们可以简单的在命令行中使用-D选项即可,如下例所示:<br><br> $ gcc -DTEST_CONFIGURATION test.c -o test<br><br> 上面的命令与在源文件中加入下列命令是等效的:<br><br> #define TEST_CONFIGURATION<br><br> 在编译命令行中定义符号常量的好处是,不必修改源文件就能改变由符<wbr>号常量控制的行为。<br><br> 五、警告功能<br><br> 当GCC 在编译过程中检查出错误的话,它就会中止编译;但检测到警告时却能<wbr>继续编译生成可执行程序,因为警告只是针对程序结构的诊断信息<wbr>,它不能说明程序一定有错误,而是存在风险,或者可能存在错误。虽然GCC提供了非常丰富的<wbr>警告,但前提是你已经启用了它们,否则它不会报告这些检测到的警告<wbr>。<br><br> 在众多的警告选项之中,最常用的就是-Wall选项<wbr>。该选项能发现程序中一系列的常见错误警告,该选项用法举例如下:<br><br> $ gcc -Wall test.c -o test<br><br> 该选项相当于同时使用了下列所有的选项:<br><br> ◆unused-function:遇到仅声明过但尚未定义的静态<wbr>函数时发出警告。<br><br> ◆unused-label:遇到声明过但不使用的标号的警告。<br><br> ◆unused-parameter:从未用过的函数参数的警告。<br><br> ◆unused-variable:在本地声明但从未用过的变量的<wbr>警告。<br><br> ◆unused-value:仅计算但从未用过的值得警告。<br><br> ◆Format:检查对printf和scanf等函数的调用<wbr>,确认各个参数类型和格式串中的一致。<br><br> ◆implicit-int:警告没有规定类型的声明。<br><br> ◆implicit-function-:在函数在未经声明就使用<wbr>时给予警告。<br><br> ◆char-subscripts:警告把char类型作为数组下<wbr>标。这是常见错误,程序员经常忘记在某些机器上char有符号。<br><br> ◆missing-braces:聚合初始化两边缺少大括号。<br><br> ◆Parentheses:在某些情况下如果忽略了括号<wbr>,编译器就发出警告。<br><br> ◆return-type:如果函数定义了返回类型<wbr>,而默认类型是int型,编译器就发出警告。同时警告那些不带返回<wbr>值的 return语句,如果他们所属的函数并非void类型。<br><br> ◆sequence-point:出现可疑的代码元素时<wbr>,发出报警。<br><br> ◆Switch:如果某条switch语句的参数属于枚举类型<wbr>,但是没有对应的case语句使用枚举元素,编译器就发出警告<wbr>(在switch语句中使用default分支能够防止这个警告<wbr>)。超出枚举范围的case语句同样会导致这个警告。<br><br> ◆strict-aliasing:对变量别名进行最严格的检查。<br><br> ◆unknown-pragmas:使用了不允许的<wbr>#pragma。<br><br> ◆Uninitialized:在初始化之前就使用自动变量。<br><br> 需要注意的是,各警告选项既然能使之生效,当然也能使之关闭 <wbr>。比如假设我们想要使用-Wall来启用个选项,同时又要关闭un<wbr>used警告,利益通过下面的命令来达到目的:<br><br> $ gcc -Wall -Wno-unused test.c -o test<br><br> 下面是使用-Wall选项的时候没有生效的一些警告项:<br><br> ◆cast-align:一旦某个指针类型强制转换时<wbr>,会导致目标所需的地址对齐边界扩展,编译器就发出警告。例如<wbr>,某些机器上只能在2或4字节边界上访问整数,如果在这种机型上把<wbr>char *强制转换成int *类型, 编译器就发出警告。<br><br> ◆sign-compare:将有符号类型和无符号类型数据进行比<wbr>较时发出警告。<br><br> ◆missing-prototypes :如果没有预先声明函数原形就定义了全局函数,编译器就发出警告<wbr>。即使函数定义自身提供了函数原形也会产生这个警告<wbr>。这样做的目的是检查没有在头文件中声明的全局函数。<br><br> ◆Packed:当结构体带有packed属性但实际并没有出现紧<wbr>缩式给出警告。<br><br> ◆Padded:如果结构体通过充填进行对齐则给出警告。<br><br> ◆unreachable-code:如果发现从未执行的代码时给<wbr>出警告。<br><br> ◆Inline:如果某函数不能内嵌(inline)<wbr>,无论是声明为inline或者是指定了-finline<wbr>-functions 选项,编译器都将发出警告。<br><br> ◆disabled-optimization:当需要太长时间或<wbr>过多资源而导致不能完成某项优化时给出警告。<br><br> 上面是使用-Wall选项时没有生效,但又比较常用的一些警告选项<wbr>。本文中要介绍的最后一个常用警告选项是-Werror<wbr>。使用该选项后,GCC发现可疑之处时不会简单的发出警告就算完事<wbr>,而是将警告作为一个错误而中断编译过程。该选项在希望得到高质量<wbr>代码时非常有用。<br><br> 六、小结<br><br> 本文介绍了GCC的基本编译过程和编译模式,并详细阐述了GCC的<wbr>一些常用选项以及警告功能。这些是在利用GCC进行应用编程时最基<wbr>本也最常用的一些内容,我们会在后续文章中继续介绍GCC的调试和<wbr>优化技术。<br> 该命令将同时编译三个源文件,即first.c、second.c和 third.c,然后将它们连接成一个可执行程序,名为test。</wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>

附录:

[参数详解]
-x language filename
   设定文件所使用的语言,使后缀名无效,对以后的多个有效.也就是根
   据约定c语言的后缀名称是.c的,而c++的后缀名是.c或者.cpp,如果
   你很个性,决定你的c代码文件的后缀名是.pig 哈哈,那你就要用这
   个参数,这个参数对他后面的文件名都起作用,除非到了下一个参数
   的使用。
   可以使用的参数吗有下面的这些
     `c, `objective-c, `c-header, `c++, `cpp-output,
     `assembler, and `assembler-with-cpp.
   看到英文,应该可以理解的。
   例子用法:
   gcc -x c hello.pig
  
-x none filename
  关掉上一个选项,也就是让gcc根据文件名后缀,自动识别文件类型
  例子用法:
  gcc -x c hello.pig -x none hello2.c
  
-c
  只激活预处理,编译,和汇编,也就是他只把程序做成obj文件
  例子用法:
  gcc -c hello.c
  他将生成.o的obj文件

-s
  只激活预处理和编译,就是指把文件编译成为汇编代码。
  例子用法
  gcc -s hello.c
  他将生成.s的汇编代码,你可以用文本编辑器察看

-e
  只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里
  面.
  例子用法:
  gcc -e hello.c > pianoapan.txt
  gcc -e hello.c | more
  慢慢看吧,一个hello word 也要与处理成800行的代码

-o
  制定目标名称,缺省的时候,gcc 编译出来的文件是a.out,很难听,如果
  你和我有同感,改掉它,哈哈
  例子用法
  gcc -o hello.exe hello.c (哦,windows用习惯了)
  gcc -o hello.asm -s hello.c

-pipe
  使用管道代替编译中临时文件,在使用非gnu汇编工具的时候,可能有些问
  题
  gcc -pipe -o hello.exe hello.c

-ansi
  关闭gnu c中与ansi c不兼容的特性,激活ansi c的专有特性(包括禁止一
  些asm inline typeof关键字,以及unix,vax等预处理宏,

-fno-asm
  此选项实现ansi选项的功能的一部分,它禁止将asm,inline和typeof用作
  关键字。
    
-fno-strict-prototype
  只对g++起作用,使用这个选项,g++将对不带参数的函数,都认为是没有显式
  的对参数的个数和类型说明,而不是没有参数.
  而gcc无论是否使用这个参数,都将对没有带参数的函数,认为城没有显式说
  明的类型
  
-fthis-is-varialble
  就是向传统c++看齐,可以使用this当一般变量使用.
  
-fcond-mismatch
  允许条件表达式的第二和第三参数类型不匹配,表达式的值将为void类型
  
-funsigned-char
-fno-signed-char
-fsigned-char
-fno-unsigned-char
  这四个参数是对char类型进行设置,决定将char类型设置成unsigned char(前
  两个参数)或者 signed char(后两个参数)
  
-include file
  包含某个代码,简单来说,就是便以某个文件,需要另一个文件的时候,就可以
  用它设定,功能就相当于在代码中使用#include<filename>
  例子用法:
  gcc hello.c -include /root/pianopan.h
  
-imacros file
  将file文件的宏,扩展到gcc/g++的输入文件,宏定义本身并不出现在输入文件
  中
  
-dmacro
  相当于c语言中的#define macro
  
-dmacro=defn
  相当于c语言中的#define macro=defn
  
-umacro
  相当于c语言中的#undef macro

-undef
  取消对任何非标准宏的定义
  
-idir
  在你是用#include"file"的时候,gcc/g++会先在当前目录查找你所制定的头
  文件,如果没有找到,他回到缺省的头文件目录找,如果使用-i制定了目录,他
  回先在你所制定的目录查找,然后再按常规的顺序去找.
  对于#include<file>,gcc/g++会到-i制定的目录查找,查找不到,然后将到系
  统的缺省的头文件目录查找
  
-i-
  就是取消前一个参数的功能,所以一般在-idir之后使用
  
-idirafter dir
  在-i的目录里面查找失败,讲到这个目录里面查找.
  
-iprefix prefix
-iwithprefix dir
  一般一起使用,当-i的目录查找失败,会到prefix+dir下查找
  
-nostdinc
  使编译器不再系统缺省的头文件目录里面找头文件,一般和-i联合使用,明确
  限定头文件的位置
  
-nostdin c++
  规定不在g++指定的标准路经中搜索,但仍在其他路径中搜索,.此选项在创建
  libg++库使用
  
-c
  在预处理的时候,不删除注释信息,一般和-e使用,有时候分析程序,用这个很
  方便的
  
-m
  生成文件关联的信息。包含目标文件所依赖的所有源代码
  你可以用gcc -m hello.c来测试一下,很简单。
  
-mm
  和上面的那个一样,但是它将忽略由#include<file>造成的依赖关系。
  
-md
  和-m相同,但是输出将导入到.d的文件里面
  
-mmd
  和-mm相同,但是输出将导入到.d的文件里面
  
-wa,option
  此选项传递option给汇编程序;如果option中间有逗号,就将option分成多个选
  项,然后传递给会汇编程序
  
-wl.option
  此选项传递option给连接程序;如果option中间有逗号,就将option分成多个选
  项,然后传递给会连接程序.
  

-llibrary
  制定编译的时候使用的库
  例子用法
  gcc -lcurses hello.c
  使用ncurses库编译程序
  
-ldir
  制定编译的时候,搜索库的路径。比如你自己的库,可以用它制定目录,不然
  编译器将只在标准库的目录找。这个dir就是目录的名称。
  
-o0
-o1
-o2
-o3
  编译器的优化选项的4个级别,-o0表示没有优化,-o1为缺省值,-o3优化级别最
  高  
  
-g
  只是编译器,在编译的时候,产生条是信息。
  
-gstabs
  此选项以stabs格式声称调试信息,但是不包括gdb调试信息.
  
-gstabs+
  此选项以stabs格式声称调试信息,并且包含仅供gdb使用的额外调试信息.
  
-ggdb
  此选项将尽可能的生成gdb的可以使用的调试信息.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值