GCC有很多的编译选项,警告选项;指定头文件、库路径;优化选项。本文针整理一下GCC的警告选项,主要依据http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html文档,并加上自己的一点小小经验。

一、总概

-w
禁止编译警告的打印。这个警告不建议使用。大约2012年底,公司代码进行一次大重构,另外从Codeblock集成开发环境转向Makefile管理,Makefile里面默认使用了-w,因而代码一直没有警告,今年个别项目开发中发现一些代码笔误导致的BUG,而这些问题可以从编译警告中知道。前几个月,领导安排我来fix这些警告。为了自己,为了后人,不建议使用-w选项。

-Werror
将所有的警告当成错误处理。此选项谨慎建议加上。有的开源库警告很多(大名鼎鼎的ffmpeg也有很多警告呢),一一改掉耗时耗人力,必要性也不大。最后,公司代码加入了一个开源库,里面有很多代码警告,可能领导又安排我来fix了。

-Wfatal-errors
遇到第一个错误就停止,减少查找错误时间。建议加上。很多人遇到错误,没有意识到从第一个开始排查。不管是编译错误,还是程序运行出错,从最开始的错误查起,是个好的做法。

-Wall开启“所有”的警告。强烈建议加上,并推荐该选项成为共识。如case语句没有default处理,有符号、无符号处理,未使用变量(特别是函数有大量未使用的数组,占用栈空间,测试发现,开辟一个未使用的8MB的数组,程序有coredump),用%d来打印地址,或%s打印int值,等,都可以发出警告。

-Wextra
除-Wall外其它的警告。建议加上。

在GCC编译时,加上必要的警告选项,可以避免很多低级错误引发的问题,我就在实际工程代码中遇到用“==”来赋值,我自己写的代码也出现过把“=”当成判断的。但是,有些错误却不是用GCC选项能解决的。比如一般项目都会自定义调试信息打印函数,但在处理可变参数类型时,往往不注意。可参考文章《一个可变参数类型检查的示例》。

二、细化

上面只是大概讲几个重要的选项。由于GCC的警告选项太多了,下面尽自己能力写一下。

-Wall选项,顾名思义,就是“所有”的意思,它包括:

-Wall包括:-Waddress   -Warray-bounds=1 (only with -O2)  -Wc++11-compat  -Wc++14-compat-Wchar-subscripts  -Wenum-compare (in C/ObjC; this is on by default in C++) -Wimplicit-int (C and Objective-C only) -Wimplicit-function-declaration (C and Objective-C only) -Wbool-compare  -Wduplicated-cond  -Wcomment  -Wformat   -Wmain (only for C/ObjC and unless -ffreestanding)  -Wmaybe-uninitialized -Wmissing-braces (only for C/ObjC) -Wnonnull  -Wopenmp-simd -Wparentheses  -Wpointer-sign  -Wreorder   -Wreturn-type  -Wsequence-point  -Wsign-compare (only in C++)  -Wstrict-aliasing  -Wstrict-overflow=1  -Wswitch  -Wtautological-compare  -Wtrigraphs  -Wuninitialized  -Wunknown-pragmas  -Wunused-function  -Wunused-label     -Wunused-value     -Wunused-variable  -Wvolatile-register-var 

但不要被它的表面意思迷惑,要不,怎么还会有-Wextra呢。-Wextra包括(有几个选项重复了,不懂原因):

          -Wclobbered  -Wempty-body  -Wignored-qualifiers -Wmissing-field-initializers  -Wmissing-parameter-type (C only)  -Wold-style-declaration (C only)  -Woverride-init  -Wsign-compare  -Wtype-limits  -Wuninitialized  -Wshift-negative-value  -Wunused-parameter (only with -Wunused or -Wall) -Wunused-but-set-parameter (only with -Wunused or -Wall)  

-Wchar-subscripts:
使用char类作为数组下标(因为char可能是有符号数)

-Wcomment:
注释使用不规范。如“/* */”注释中还包括“/*”。我在项目源码发现过,不止一处。

-Wmissing-braces
括号不匹配。在多维数组的初始化或赋值中经常出现。下面a没有完整被初始化,b完整初始化:
int a[2][2] = { 0, 1, 2, 3 };
int b[2][2] = { { 0, 1 }, { 2, 3 } };

-Wparentheses
括号不匹配,在运算符操作或if分支语句中,可能会出现此警告。
如“a&&b||c^d”会出现警告。下面代码片段也会有警告
{
if (a)
  if (b)
    foo ();
else
  bar (); // 这个else实际是if (b)的分支,不是if (a),因此,要用括号来表明其属于哪个分支
}

这类bug隐藏得深,建议显式地加上括号。

-Wsequence-point
如出现i=i++这类代码,则报警告。-Wall默认有该警告

-Wswitch-defaultcase
没有default时,报警告

-Wunused-but-set-parameter
设置了但未使用的参数警告

-Wunused-but-set-variable
设置了但未使用的变量警告

-Wunused-function 
声明但未使用函数

-Wunused-label
未使用的标签,比如用goto会使用label,但在删除goto语句时,忘了删除label。

-Wunused-variable
未使用的变量

-Wmaybe-uninitialized
变量可能没有被初始化。特别是在有if语句或switch语句中,最好在声明变量时加上初始化。
下面代码片段中,当y不是1、2、3时,x没有明确的值,是不安全的。
{
int x;
switch (y)
  {
  case 1: x = 1;
    break;
  case 2: x = 4;
    break;
  case 3: x = 5;
  }
foo (x);
}

-Wfloat-equal
对浮点数使用等号,这是不安全的。
{
float d = 2.0;
if (d == i)
{
  ...
}
}
-Wreturn-type
函数有返回值,但函数体个别地方没有返回值(特别是有if判断,可能忘记在else添加返回值)。
int foo()
{
 if(a==1)
 {
      return ok;
 }
 // no return here
}

-Wpointer-sign
指针有符号和无符号的错误传参。如函数使用unsigned char*,但传入char*指针。

-Wsign-compare
有符号和无符号比较。

-Wconversion-null

-Wsizeof-pointer-memaccess
在sizeof中经常出现,下面代码片段中,this为指针,4字节,无法保证完整初始化类。
memset(this, 0, sizeof(this));

-Wreorder
C++出现,构造函数中成员变量初始化与声明的顺序不一致。

-Woverflow
范围溢出。

-Wshadow
局部变量覆盖参数、全局变量,报警告

参考资料:

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

李迟 2015.12.11 周五 夜

GCC编译警告选项的学习相关推荐

  1. gcc: 新编译警告选项;dangling-pointer

    文章目录 前言 介绍-Wdangling-pointer -Wdangling-pointer=1 -Wdangling-pointer=2 相关的一个bug 工作种遇到过的类似问题 前言 随着时间的 ...

  2. linux gcc编译常见问题,常见gcc编译警告整理以及解决方法 - 常见gcc编译警告整理以及解决方法...

    三.常见gcc编译警告整理以及解决方法 1.warning: no newline at end of file 在文件最后一行加上回车键 解释:在<Rationale for the C99 ...

  3. gcc 编译安全选项

    目录 一 GCC 安全编译简介 1 ASLR 地址随机 2 栈溢出保护 3 FORTIFY 4 RELRO 二  动态库搜索路径 RPATH VS. RUNPATH 三 其它 checksec 四 文 ...

  4. gcc 编译命令选项$@ $^ $

    一些常见的自动化变量说明如下: (1) $@ --目标文件的名称: (2) $^ --所有的依赖文件,以空格分开,不包含重复的依赖文件: (3) $< --第一个依赖文件的名称. (4) $?  ...

  5. 【转】GCC警告选项例解 -- 不错

    原文网址:http://blog.csdn.net/hcx25909/article/details/7383716 程序员是追求完美的一族,即使是一般的程序员大多也都不想看到自己的程序中有甚至那么一 ...

  6. gcc编译以及Makefile与GDB调试

    一:编译选项:       gcc常用编译的选项: -c 表示编译源文件,只编译并生成目标文件. -E 只运行 C 预编译器. -o 表示输出目标文件 -g 表示在目标文件中产生调试信息, 用于 gd ...

  7. Linux里gcc编译过程分析和ELF文件格式学习

    GCC编译器背后的故事及常用命令.了解ELF文件格式 前言 一.GCC简介 二.GCC背后的战友 1.Binutils 2.C运行库 三.GCC编译流程及对应命令 1.编译流程图及命令框图 2.实践操 ...

  8. Ubuntu18.04系统下,gcc编译过程分析、命令参数介绍及ELF文件格式学习

    GCC编译器背后的故事及常用命令.了解ELF文件格式 文章目录 GCC编译器背后的故事及常用命令.了解ELF文件格式 前言 一.GCC简介 二.GCC背后的战友 1.Binutils 2.C运行库 三 ...

  9. GCC 警告选项 -Werror

    cc1plus: all warnings being treated as errors 解决办法:只需要找到相应的Makefile,去掉编译选项中的 -Werror 即可. --Werror 视警 ...

最新文章

  1. (11/24) css进阶:Less文件的打包和分离
  2. 网页前端套java数据_【java】网页/移动前端需要的数据,最好一个接口包含所有数据么?...
  3. telnet 查看端口是否可访问
  4. [链表]---链表中环的入口节点
  5. oracle中的sga和pga
  6. ?php $postsperpage=9;?,php – 如何在自定义WP_Query Ajax上实现分页
  7. this java_Java this关键字详解
  8. 《OpenGL编程指南(原书第8版)》——计算着色器
  9. 期待!小米电视5官曝新功能:可准确识别家中每一个人
  10. matlab 时频分析(短时傅里叶变换、STFT)
  11. idea 初始界面_IDEA 初始配置教程
  12. c# rar压缩解压缩
  13. VC调用Lingo并转化成 QT 工程编写一个特定的解决线性问题的软件
  14. 【OR】YALMIP Bilevel规划
  15. 安川机器人程序还原_安川机器人程序示例
  16. 报错:fdfs while reading from socket: (timed out))
  17. flutter在IOS上的登录实现——QQ登录、微信登录、自动识别手机号一键登录、apple登录
  18. MySqlDataAdapter.Update -- 报错
  19. 雅可比(Jacobi)计算特征值和特征向量
  20. Qt中Label标签的使用

热门文章

  1. 高通第一财季营收107亿美元 净利润超过30亿美元
  2. iPhone 13外观四年以来首次改动:真的尽力了
  3. 爆料称华为P50系列即将进入量产 或将于下月发布
  4. 和平精英、宾果消消消等多款游戏APP存隐私不合规行为
  5. 下半年登场!小米MIX 4概念图曝光:有望首发屏下摄像头
  6. 跑山么、后浪们?2.0T+237匹大马力后驱CT4山路试驾体验
  7. 罗永浩宣布要做带货一哥后,合作单子如雪花般飞来
  8. 小米10预计春节后见 售价超3500元没悬念
  9. 京东到家公布双十二成绩:销售额同比增长1.2倍
  10. 唏嘘!知名音乐站再传倒闭:官网、App挂掉,“留下了时代的眼泪...”