GCC一些有用的技巧

原创
2014/02/26 10:37
阅读数 2.6K

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
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
7 收藏
0
分享
返回顶部
顶部