GCC编译器(2)

来源:互联网 发布:激光笔软件 编辑:程序博客网 时间:2024/05/18 21:49

4、警告选项

在编译过程中,编译器的报错和警告信息对于程序员来说是非常重要的信息,GCC包含完整的出错检查和警告提示功能,它可以帮助Linux程序员尽快找出错误的或潜在的错误代码,从而写过更优美的代码。GCC的编译器警告选项如下表:

类型说明-Wall启用所有警告信息-Werror在发生警告时取消编译操作,即将警告看作是错误-w禁用所有警告信息

 

下面看一段代码,使用GCC编译,同时开启警告信息:

1
2
3
4
5
6
7
8
9
#include <stdio.h>
void main ()
{
    intx;
    for(x=1;x<=10;x++)
    {
        printf("%d\n",x);
    }
}

对上面的代码进行编译连接:

$ gcc -Wall example3.c -o example3

example3.c:2:6: 警告: ‘main’的返回类型不是‘int’ [-Wmain]

从上面的输出看到,GCC给出了警告信息,意思是main函数的返回值被声明为void,但实际应该是int。

此外,GCC还提供了许多以-W开头的选项,允许用户指定输出某个特定的警告,例如:

  • -Wcomment:出现注释嵌套时发出警告。
  • -Wconversion:如果程序中存在隐式类型转换,则发出警告。
  • -Wformat:检查printf和scanf等格式化输入输出函数的格式字符串和参数类型的匹配情况,如果发现不匹配则发出警告。
  • -Winline:如果函数不能被内联,则发出警告。
  • -Wlong-long:如果使用了long long型数据,则发出警告。
  • -Wmain:如果main函数的返回类型不是int型,或者调用main函数时使用的参数数目不正确,则发出警告。
  • -Wmissing-declarations:如果定义了全局函数,但却没有在头文件中声明,则发出警告。
  • -Wparentheses:在某些情况下,如果忽略掉了括号,则会发出警告。
  • -Wreturn-type:如果函数定义了返回类型,而默认类型是int型,编译器会发出警告。
  • -Wuninitialized:如果使用的自动变量没有被初始化,则发出警告。
  • -Wundef:如果在#if宏中使用了未定义的变量做判断,则发出警告。
  • -Wunused:如果声明的变量或static型函数没有使用,则发出警告。

下面使用GCC编译一段程序,来说明开启警告信息的必要性:

1
2
3
4
5
6
7
#include<stdio>
int main()
{
    doublex;
    printf("%d\n",x); /* 这里将%f误输为%d */
    return0;
}

对上面的程序进行编译:

$ gcc example4.c -o example4

可以看到,编译并没有报错,运行可执行文件,输出结果为:

$ ./example4

134513689

这不是想要的输出结果,如果在上面的编译中加入-Wformat或-Wall选项,即:

$ gcc -Wformat example4.c -o example4

$ gcc -Wall example4.c -o example4

GCC给出如下警告信息:

example4.c: 在函数‘main’中:

example4.c:5:5: 警告: 格式 ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat]

格式字符串和参数类型的不匹配会导致程序运行错误,所以这是是非常有用的警告选项。

下面使用GCC编译一段程序,使用-Wparentheses选项对其中的括号进行检查。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<stdio>
int main()
{
    inta=1;
    intb=0;
    intc=1;
    if(a&&b||c)
    {
        ;
    }
    if(a==1)
        if(b==1)
            printf("b=1\n");
    else
        printf("b!=1\n");
    return0;
}

 

对上面的程序进行编译:

$ gcc -Wparentheses example5.c -o example5

example5.c: 在函数‘main’中:

example5.c:7:5: 警告: 建议在‘||’的操作数中出现的‘&&’前后加上括号 [-Wparentheses]

example5.c:11:7: 警告: 建议显式地使用花括号以避免出现有歧义的‘else’ [-Wparentheses]

所以GCC编译器的警告选项对程序员来说是非常重要的。

 

5、连接选项

GCC编译器提供的连接器选项如下表:

类型说明-Idirectory向GCC的头文件搜索路径中添加新的目录-Ldirectory向GCC的库文件搜索路径中添加新的目录-llibrary提示连接程序在创建可执行文件时包含指定的库文件-static强制使用静态链接库-shared生成动态库文件

 

先来理解一下头文件和库文件这两个概念:

头文件包含变量和函数的声明,但没有定义函数的实现。函数的具体实现实在库文件中完成的,库文件可分为静态库和动态库,静态库是指编译连接时,将库文件的代码全部加入到可执行文件中,这样运行时就不需要库文件了。静态库的后缀名一般为“.a”。动态库是指在编译连接时并不将库文件的代码加入到可执行文件中,而是在程序执行时由运行时连接文件加载库文件,这样可以节省系统的开销。动态库的后缀名一般为“.so”。

例如我们编译是用-I选项来指定头文件的路径:

$ gcc example.c –o example –I/home/xxx/include

头文件所对应的库文件,如果没有特别指定时,GCC会到默认的搜索路径进行查找。

使用-L选项来指定库文件的路径,例如:

$ gcc example.c –o example –L/home/xxx/lib

GCC编译器在默认情况下使用动态库,但如果使用了-static选项,连接器将忽略动态库,强制使用静态链接库,即使用如下命令:

$ gcc example.c –o example –static –lm

此时静态库文件中的代码全部包含到可执行文件中,所以生成的可执行文件比较大。

 

 

本节完…

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小米6不断重启怎么办 小米6一直重启怎么办 小米6自动重启怎么办 手机的开机键坏了怎么办 小米6频繁重启怎么办 小米6安装xp卡米怎么办 刷机失败反复重启怎么办 红米手机很卡怎么办啊 红米2a显示图标怎么办 手机一直处于开机状态怎么办 vivo手机进水开不了机怎么办 魅蓝s6锁了怎么办 pos机刷卡刷多了怎么办 红米5a开不机怎么办 魅族双亲要密码怎么办? 苹果wi-fi网速慢怎么办 腾达宽带用户名密码忘了怎么办 无线网秘密忘了怎么办 wan口设置已断开怎么办 中兴手机忘记解锁图案怎么办 u盘显示参数错误怎么办 硬盘vc加密密码忘了怎么办 软件文件移动到其他盘打不开怎么办 u盘无法复制文件怎么办 u盘大文件不能拷怎么办 abc看图打印不了怎么办 百度云大文件慢怎么办 手机视频缩略图加载失败怎么办 电脑突然卡住不动了怎么办 word文档被锁住了怎么办 手机qq磁盘已满怎么办 不小心格式化了硬盘怎么办 移动硬盘插上显示要格式化怎么办 微信网络特别慢怎么办 苹果六网速太慢怎么办 小米手机wifi网速慢怎么办 苹果8蜂窝上网慢怎么办 苹果6s4g网速慢怎么办 苹果7上网速度慢怎么办 银行转账到别人账户怎么办 银行转账转错账户怎么办