gcc编译器的使用

gcc在开发初期的确是定位在一款C编译器,从其名字就可以推测出来:GNU C Compiler。然而经过十多年的发展,gcc的含义已经悄然改变,成为GNU Compiler Collection,同时支持C、C++、Objective C、Chill、Fortran和Java等语言。这里以几个实例介绍gcc编译器的用法。作为自由软件的旗舰项目,gcc的功能是如此强大,这里无法列举其每一个选项,有需要的话可以参考GNU gcc手册。


编译第一个C程序


假设我们已经有了一个C文件名为summary.c,其内容如下:

#include <stdio.h>

int summary(int n);

int main()

{

int i,result;

result=0;

for(i=1;i<=100;i++)

{

result+=i;

}

printf("Summary[1-100]=%d\n",result);

printf("Summary[1-450]=%d\n",summary(450));

return 0;

}

int summary(int n)

{

int sum=0;

int i=0;

for(i=1;i<=n;i++)

{

sum+=i;

}

return sum;

}


要编译一个C语言程序,只要简单的使用gcc命令后跟一个C源文件作为参数。下面这条命令编译文件summary.c。


$ gcc summary.c


编译之后产生的可执行文件叫做a.out,位于当前目录下。下面执行这个程序


$ ./a.out


不过,看起来似乎没有人喜欢a.out这个默认的文件名。gcc提供了-o选项让用户指定可执行文件的文件名。下面这条命令将summary.c编译成可执行文件sum。


$ gcc -o sum summary.c

$ ./sum


同编译有关的选项


读者已经知道如何使用gcc生成可执行文件了:只需要1行命令,2个(或4个)单词。有点出乎意料的容易。是吗?然而在很多情况下,程序员需要的不只是一个可执行程序那么简单。一些场合需要目标代码,有些时候程序员又要得到汇编代码等,gcc很擅长满足这些需求,下表列出了和编译有关的若干选项。


                              和编译有关的选项
---------------------------------------------------------------------------------------------
   选项   |                                      功能
---------------------------------------------------------------------------------------------
    -c    |     只激活预处理、编译和汇编,生成扩展名为.o的目标代码文件
    -S    |     只激活预处理和编译,生成扩展名为.s的汇编代码文件
    -E    |     只激活预处理,并将结果输出至标准输出
    -g    |     为调试程序(如gdb)生成相关信息
---------------------------------------------------------------------------------------------


-c选项在编写大型程序的时候是必须的。存在依赖关系的源代码文件总是要首先编译成目标代码,最后一起连接成可执行文件。当然,如果一个程序拥有超过3个源代码文件,那就应该考虑使用make工具了——介绍makefile的语法已经超出了本书的范围,有兴趣的读者可以参考Linux编程方面的书籍。一些C语言教程也会对Linux的makefile做了简要介绍,如Al Kelley和Ira Phol的A Book on C(中文版《C语言教程》,机械工业出版社)。


在使用-E选项的时候要格外小心,不要想当然地以为gcc会把结果输出到某个文件中。恰恰相反,gcc是在屏幕上(准确的说是标准输出)显示其处理结果的。只要程序中包含了标准库的头文件,那么预处理后的结果一定是很长的,应该使用重定向将其输出到一个文件中。


$ gcc -E summary.c > pre_sum


下面这个例子可以帮助C语言初学者理解他们错在哪里。


$ cat macro.c


/* macro.c */
#define SUB(X,Y) X*Y
int main()
{
int result;
result = SUB(2+3,4);
return 0;
}


$ gcc -E macro.c


...
int main()
{
int result;
result = 2+3*4;
return 0;
}


选项-g是为调试准备的。


优化选项


程序员总是希望自己的作品执行起来更为快速、高效。这除了取决于代码本身的质量,编译器也在其中发挥了不可小视的作用。同一条语句可以被翻译成不同的汇编代码,但是执行效率却大相径庭。有些编译器不够聪明,他们甚至不愿理会程序员在源代码中的“暗示”,因此只能生成效率低下的目标代码。gcc显然不在此列。除了足够“聪明”之外,gcc还提供了各种优化选项供程序员选择。为了得到经过特别优化的代码,最简单的方法是通过使用-Onum选项。


gcc提供了3个级别的优化选项,从低到高依次是-O1、-O2和-O3。理论上-O3可以生成执行效率最高的目标代码。然而,优化程度越高就意味着冒更大的风险。通常来说,-O2选项就可以满足绝大多数的优化需求,也足够安全。


事实上,-O1、-O2、-O3是对多个优化选项的“打包”。用户也可以手动指定使用哪些优化选项。gcc的优化选项通常都很长,以至于有时候看上去像是一堆随机字符序列,有兴趣的读者可以参考gcc的官方手册。


一个比较“激进”的优化方案是使用-march选项。gcc会为特定的CPU编译二进制代码,产生的代码只能在该型号的CPU上运行。例如:


$ gcc -O2 -march=pentium4 summary.c


上面这条命令在64位机器上会产生错误:


summary.c:1:错误:您选择的CPU不支持x86-64指令集
summary.c:1:错误:您选择的CPU不支持x86-64指令集


如果没有特殊需要,不建议使用-march选项。另外,一些软件在使用优化选项编译后会产生各种问题,例如Linux系统的基本C程序库glibc就不应该使用优化选项编译。


编译C++程序:g++


下面是一个名为hello.cpp的C++源文件的内容:


#include<iostream>

using namespace std;

int main()

{

cout<<"Hello World !!"<<endl;

return 0;

}


gcc命令可以编译C++源文件,但不能自动和C++程序使用的库连接。因此通常使用g++命令来完成C++程序的编译和连接,该程序会自动调用gcc实现编译。


$ g++ -o hello hello.cpp


g++的选项和gcc基本一致。上面的例子编译C++文件hello.cpp,并把生成的可执行文件命名为hello。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值