本文转载至:http://my.oschina.net/sundq/blog/203177
Linux上的gcc编译器有需要命令选项,我们不可能全部记住它们,今天我们介绍几个不常用但是非常有用的选项。以下的示例实在GCC 4.7.3上演示的。
-save-temps
gcc编译一个程序需要四步:
- 第一步:展开所有定义的宏和包含的文件,并去除说有注释。
- 第二步:在第一步的基础上,产生汇编语言指令。
- 第三步:汇编编译器将汇编指令转换为机器指令。
- 第四步:连接器处理所有没有找的符号(symbols ),然后生成一个可执行的文件。
所以gcc编译文件的最终结果是一个可执行文件,但是可能有时候我们需要查看某个特定的宏是如何展开的,或者是查看汇编语言代码,在编译时加上-save-temps选项可以查看这些中间输出信息。如执行下面命令:
$ gcc -Wall -save-temps helloworld.c -o helloworld
这样除了生成最终的可执行文件,会额外生成两个文件helloworld.i和helloworld.s,前者是预处理器处理的结果,后者是汇编指令代码。
-Wextra
大多数情况下,我们使用-Wall选项开输出所有的警告信息,但是这个选项并不能输出所有的警告信息,如下面的警告信息会被忽略:
- 忘记参数类型
- 指针与整数零的逻辑比较
- 有歧义的虚基类
我们可以看一下面的代码:
#include<stdio.h>
void func(a)
{
printf("\n func() is passed parameter [%d]\n",a);
return;
}
int main(void)
{
printf("\n HELLO \n");
func(0xFFFFF);
return 0;
}
很明显,函数func的函数参数没有指定类型,这样会导致编译器将参数类型默认为int,这样很可能会造成严重的bug。我们可以看一下加上-Wextra选项的效果:
$ gcc -Wall -Wextra helloworld.c -o helloworld
helloworld.c: In function 'func':
helloworld.c:4:6: warning: type of 'a' defaults to 'int' [-Wmissing-parameter-type]
可以看到有警告输出,这样就可以很容易的修改可能存在的问题。
再看一下另外一个例子:
#include<stdio.h>
void func()
{
int a = -1;
int *ptr = &a;
if(ptr >= 0)
{
a = a+1;
}
printf("\n a = [%d]\n",a);
return;
}
int main(void)
{
printf("\n HELLO \n");
func();
return 0;
}
可以看到指针ptr与0比较,显然这是没有必要的,因为该指针永远大于0,很可能的一种情况是*ptr与0比较,这样的错误很难被发现,但是如果使用-Wextra就可以很容易的发现,看看下面的编译输出结果:
$ gcc -Wall -Wextra helloworld.c -o helloworld
helloworld.c: In function 'func':
helloworld.c:9:12: warning: ordered comparison of pointer with integer zero [-Wextra]
-Wfloat-equal
很多新手在最开始的时候使用==和!=来比较浮点数,这个错误编译前一般情况下是不给出警告的,但是加上-Wfloat-equal就可以显示这个警告了:
#include<stdio.h>
void func(float a, float b)
{
printf("\n Inside func() \n");
if(a == b)
{
printf("\n a == b\n");
}
return;
}
int main(void)
{
printf("\n HELLO \n");
func(1.345, 1.345678);
return 0;
}
执行如下命令进行编译:
$ gcc -Wfloat-equal helloworld.c -o helloworld
helloworld.c: In function 'func':
helloworld.c:7:10: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
可以看到,出现不安全比较的警告。
@file
如果在编译的时候有很多选项使用,那么可以把这些选项写到一个文件中,然后使用@file来引用这些选项,如下方法
$ gcc @options helloworld.c -o helloworld