本文共 2148 字,大约阅读时间需要 7 分钟。
本文转载至:
Linux上的gcc编译器有需要命令选项,我们不可能全部记住它们,今天我们介绍几个不常用但是非常有用的选项。以下的示例实在GCC 4.7.3上演示的。
gcc编译一个程序需要四步:
所以gcc编译文件的最终结果是一个可执行文件,但是可能有时候我们需要查看某个特定的宏是如何展开的,或者是查看汇编语言代码,在编译时加上-save-temps选项可以查看这些中间输出信息。如执行下面命令:
$ gcc -Wall -save-temps helloworld.c -o helloworld
这样除了生成最终的可执行文件,会额外生成两个文件helloworld.i和helloworld.s,前者是预处理器处理的结果,后者是汇编指令代码。
大多数情况下,我们使用-Wall选项开输出所有的警告信息,但是这个选项并不能输出所有的警告信息,如下面的警告信息会被忽略:
我们可以看一下面的代码:
#includevoid 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 helloworldhelloworld.c: In function 'func':helloworld.c:4:6: warning: type of 'a' defaults to 'int' [-Wmissing-parameter-type]
可以看到有警告输出,这样就可以很容易的修改可能存在的问题。
再看一下另外一个例子:
#includevoid 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 helloworldhelloworld.c: In function 'func':helloworld.c:9:12: warning: ordered comparison of pointer with integer zero [-Wextra]
很多新手在最开始的时候使用==和!=来比较浮点数,这个错误编译前一般情况下是不给出警告的,但是加上-Wfloat-equal就可以显示这个警告了:
#includevoid 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 helloworldhelloworld.c: In function 'func':helloworld.c:7:10: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
可以看到,出现不安全比较的警告。
如果在编译的时候有很多选项使用,那么可以把这些选项写到一个文件中,然后使用@file来引用这些选项,如下方法
$ gcc @options helloworld.c -o helloworld