c++编译时打开warning-as-error,并在特定情况下关闭某些warning检查

在cmake中开启warning-as-errors检查

为提升c++代码质量,将所有warning当作error处理,可有效提升代码质量。在cmake中开启的方式如下:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp  -Wall -Wextra -Werror")

其中,-Wall打开大部分warning,-Wextra打开一些特定需求。前者不包含后者

关闭特定warning的办法

关闭warning有相应语法如下:
gcc关闭“有无符号数据对比”检查的warning (即sign-compare)

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-compare"
/// some code ...
#pragma GCC diagnostic pop

clang关闭“有无符号数据对比”检查的warning (即sign-compare)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-compare"
/// some code ...
#pragma clang diagnostic pop

使用宏关闭特定warning (gcc / clang)

定义关闭warning的宏(gcc / clang)

#ifdef __GNUC__
#define COMPILER_PRAGMA(X) _Pragma(#X)

#define DISABLE_WARNING_PUSH COMPILER_PRAGMA(GCC diagnostic push)

#define DISABLE_WARNING(warningName) \
  COMPILER_PRAGMA(GCC diagnostic ignored #warningName)

#define DISABLE_WARNING_ALL DISABLE_WARNING(-Wall) DISABLE_WARNING(-Wextra)

#define DISABLE_WARNING_POP COMPILER_PRAGMA(GCC diagnostic pop)

#elif defined(__clang__)
#define COMPILER_PRAGMA(X) _Pragma(#X)

#define DISABLE_WARNING_PUSH COMPILER_PRAGMA(clang diagnostic push)

#define DISABLE_WARNING(warningName) \
  COMPILER_PRAGMA(clang diagnostic ignored #warningName)

#define DISABLE_WARNING_ALL DISABLE_WARNING(-Wall)

#define DISABLE_WARNING_POP COMPILER_PRAGMA(clang diagnostic pop)

#endif

使用关闭warning的宏

DISABLE_WARNING_PUSH
DISABLE_WARNING_ALL // 关闭了"-Wall" / "-Wextra"相关的warning
// some code ...
DISABLE_WARNING_POP

警告参数说明

开启和关闭告警方法

1、-w (小写)禁止所有警告消息。

2、以“-W”(大写)开头开启特定的警告;

例如:

  • -Wreturn-type(返回值告警),

  • -Wsign-compare(有符号和无符号对比告警)

  • -Wall (除extra外的所有告警)

  • -Wextra (all外的其他告警)

如 $ gcc -Wall test.c -o test

3、以“-Wno-”开头关闭特定的警告;

例如:

-Wno-return-type (取消返回值告警)

-Wno-sign-compare(取消有符号和无符号对比告警)

如:$ gcc -Wall -Wno-unused test.c -o test

4、批量警告

  • -Wall
    等价于一次添加以下warning

◆unused-function:遇到仅声明过但尚未定义的静态函数时发出警告。
◆unused-label:遇到声明过但不使用的标号的警告。
◆unused-parameter:从未用过的函数参数的警告。
◆unused-variable:在本地声明但从未用过的变量的警告。
◆unused-value:仅计算但从未用过的值得警告。
◆Format:检查对printf和scanf等函数的调用,确认各个参数类型和格式串中的一致。
◆implicit-int:警告没有规定类型的声明。
◆implicit-function-:在函数在未经声明就使用时给予警告。
◆char-subscripts:警告把char类型作为数组下标。这是常见错误,程序员经常忘记在某些机器上char有符号。
◆missing-braces:聚合初始化两边缺少大括号。
◆Parentheses:在某些情况下如果忽略了括号,编译器就发出警告。
◆return-type:如果函数定义了返回类型,而默认类型是int型,编译器就发出警告。同时警告那些不带返回值的 return语句,如果他们所属的函数并非void类型。
◆sequence-point:出现可疑的代码元素时,发出报警。
◆Switch:如果某条switch语句的参数属于枚举类型,但是没有对应的case语句使用枚举元素,编译器就发出警告(在switch语句中使用default分支能够防止这个警告)。超出枚举范围的case语句同样会导致这个警告。
◆strict-aliasing:对变量别名进行最严格的检查。
◆unknown-pragmas:使用了不允许的#pragma。
◆Uninitialized:在初始化之前就使用自动变量。

  • -Wextra
    等价于一次添加以下warning

-Wclobbered
-Wcast-function-type
-Wempty-body
-Wignored-qualifiers 如果函数的返回类型具有类型限定符(如const ,则发出警告。 对于ISO C这样的类型限定符没有效果,因为函数返回的值不是左值。 对于C ++来说,警告只是针对标量类型或void发出的。 ISO C禁止在函数定义上使用合格的void返回类型,所以这种返回类型总是会在没有这个选项的情况下收到警告。
-Wimplicit-fallthrough=3
-Wmissing-field-initializers
-Wmissing-parameter-type (C only)
-Wold-style-declaration (C only)
-Woverride-init
-Wsign-compare (C only)
-Wtype-limits 由于数据类型范围有限而导致比较始终为真或始终为false,但不警告常量表达式。例如,警告如果将一个无符号变量与<或与0进行比较>=
-Wuninitialized
-Wshift-negative-value (in C++03 and in C99 and newer)
-Wunused-parameter (only with -Wunused or -Wall)
-Wunused-but-set-parameter (only with -Wunused or -Wall)

5、不包含于以上的部分warning

◆cast-align:一旦某个指针类型强制转换时,会导致目标所需的地址对齐边界扩展,编译器就发出警告。例如,某些机器上只能在2或4字节边界上访问整数,如果在这种机型上把char *强制转换成int *类型, 编译器就发出警告。
◆sign-compare:将有符号类型和无符号类型数据进行比较时发出警告。
◆missing-prototypes :如果没有预先声明函数原形就定义了全局函数,编译器就发出警告。即使函数定义自身提供了函数原形也会产生这个警告。这样做的目的是检查没有在头文件中声明的全局函数。
◆Packed:当结构体带有packed属性但实际并没有出现紧缩式给出警告。
◆Padded:如果结构体通过充填进行对齐则给出警告。
◆unreachable-code:如果发现从未执行的代码时给出警告。
◆Inline:如果某函数不能内嵌(inline),无论是声明为inline或者是指定了-finline-functions 选项,编译器都将发出警告。
◆disabled-optimization:当需要太长时间或过多资源而导致不能完成某项优化时给出警告。

其他选项

  • -Wshadow
    当一个局部变量遮盖住了另一个局部变量,或者全局变量时,给出警告。很有用的选项,建议打开。 -Wall 并不会打开此项。

  • -Wpointer-arith
    对函数指针或者void *类型的指针进行算术操作时给出警告。也很有用。 -Wall 并不会打开此项。

  • -Wcast-qual
    当强制转化丢掉了类型修饰符时给出警告。 -Wall 并不会打开此项。

  • -Waggregate-return
    如果定义或调用了返回结构体或联合体的函数,编译器就发出警告。

  • -Winline
    无论是声明为 inline 或者是指定了-finline-functions 选项,如果某函数不能内联,编译器都将发出警告。如果你的代码含有很多 inline 函数的话,这是很有用的选项。

  • -Werror
    把警告当作错误。出现任何警告就放弃编译。

  • -Wunreachable-code
    如果编译器探测到永远不会执行到的代码,就给出警告。也是比较有用的选项。

  • -Wcast-align
    一旦某个指针类型强制转换导致目标所需的地址对齐增加时,编译器就发出警告。

  • -Wundef
    当一个没有定义的符号出现在 #if 中时,给出警告。

  • -Wredundant-decls
    如果在同一个可见域内某定义多次声明,编译器就发出警告,即使这些重复声明有效并且毫无差别。

参考
gcc, g++编译时消除特定警告的方法
【GCC】gcc警告选项汇总–编辑中|gcc编译选项

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值