用于启用详尽且详细的g ++警告的标志

Sda*_*ons 113 c++ warnings g++

通常在C下gcc,我将从以下一组警告标志开始(从多个来源痛苦地组装):

-Wall -Wextra -Wformat-nonliteral -Wcast-align -Wpointer-arith -Wbad-function-cast \
-Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -Winline -Wundef \
-Wnested-externs -Wcast-qual -Wshadow -Wwrite-strings -Wno-unused-parameter \
-Wfloat-equal -pedantic -ansi
Run Code Online (Sandbox Code Playgroud)

我将使用这组警告构建(至少我的调试版本)并修复我可能做的所有事情(通常是一切),然后只删除标记,如果它们不相关或不可修复(几乎从不这样).有时,-Werror如果我必须在编译时离开,我也会添加.

我只是拿起C++(是的,我落后了15年),我想从右脚开始.

我的问题是:是否有人为C++预先编译了类似的完整警告标志集g++?(我知道其中很多都是一样的.)

Dav*_*one 124

我经历了一个最小的包含,它应该得到最高级别的警告.然后我从该列表中删除了一组警告,我觉得这些警告实际上并没有表明发生了什么不好的事情,或者在实际构建中使用了太多的误报.我评论为什么我排除的每一个都被排除在外.这是我最后一组建议的警告:

-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused

存在可疑警告:

  • 我包括-Wno-unused因为我经常有变量,我知道我将在以后使用,但还没有为其编写的功能.删除有关它的警告允许我以我喜欢的方式写下偶尔推迟实现的东西.每隔一段时间关闭一次是很有用的,以确保没有任何东西从裂缝中滑落.

  • -Wdisabled-optimization似乎是一个强大的用户偏好设置.我刚刚将这一个添加到我的构建中(仅出于显而易见的原因,仅针对优化的构建)并且它没有改变任何东西,所以它似乎不是特别繁琐的警告,至少对于我编码的方式.我包含它(即使触发此警告的代码不一定是错误的)因为我相信使用我的工具而不是反对它们.如果gcc告诉我它不能为我编写它的方式优化代码,那么我应该考虑重写它.我怀疑触发此警告的代码可能会受益于更加模块化,无论如何,所以虽然代码在技术上不是错误的(可能),但风格上可能是这样.

  • -Wfloat-equal警告安全平等比较(特别是与非计算值-1的比较).在我的代码中我使用它的一个例子是我有一个float向量.我通过这个向量,有一些我无法评估它们应该是什么的元素,所以我将它们设置为-1.0f(因为我的问题只使用正数,-1不在域内).我稍后通过并更新-1.0f值.它不容易适用于不同的操作方法.我怀疑大多数人都没有这个问题,并且浮点中的确切数字的比较可能是一个错误,所以我将它包含在默认列表中.

  • -Wold-style-cast在我正在使用的库代码中有很多误报.特别是,网络中使用的htonl函数系列以及我正在使用的Rijndael(AES)加密实现具有它向我发出警告的旧式转换.我打算替换这两个,但我不确定我的代码中是否还有其他任何东西会抱怨.但是,大多数用户可能默认启用此功能.

  • -Wsign-conversion是一个艰难的(几乎没有列出名单).在我的代码中打开它会产生大量的警告(100+).几乎所有人都是无辜的.但是,在我不确定的地方,我一直小心使用有符号整数,虽然对于我的特定问题域,由于我做了大量的整数除法,我通常会使用无符号值略微提高效率.我牺牲了这种效率,因为我担心意外地将有符号整数提升为无符号然后除法(这不是安全的,不像加法,减法和乘法).打开此警告允许我安全地将大多数变量更改为无符号类型,并在其他一些位置添加一些强制转换.它目前有点难以使用,因为警告并不那么聪明.例如,如果这样做,则会unsigned short + (integral constant expression)将结果隐式提升为int.然后,如果您将该值分配给unsignedunsigned short,即使它是安全的,它也会警告潜在的符号问题 .对于几乎所有用户来说,这绝对是最可选的警告.

  • -Wsign-promo:看-Wsign-conversion.

  • -Wswitch-default似乎没有意义(如果你明确列举了所有可能性,你并不总是想要一个默认情况).但是,打开此警告可以强制执行一些可能是个好主意的事情.对于您明确要忽略除列出的可能性之外的所有内容(但可能有其他数字)的情况,然后输入default: break;以使其显式化.如果您明确列举了所有可能性,那么打开此警告将有助于确保您输入类似assert(false)的内容以确保您实际涵盖了所有可能的选项.它可以让您明确问题的域名并以编程方式强制执行.但是,你必须要小心,只是在任何地方坚持断言(假).它比默认情况下无所作为更好,但与assert一样,它在发布版本中不起作用.换句话说,您不能依赖它来验证您从网络连接或您无法完全控制的数据库中获得的数字.例外或早退是处理这种情况的最佳方法(但仍需要你有一个默认情况!).

  • -Werror对我来说是一个重要的.在具有多个目标的多线程构建中编译大量代码时,很容易发出警告.将警告转换为错误可确保我注意到它们.

然后有一组警告没有包含在上面的列表中,因为我没有发现它们有用.这些是警告和我对我为什么不将它们包含在默认列表中的评论:

没有警告:

  • -Wabi不需要因为我没有组合来自不同编译器的二进制文件.无论如何我试着用它进行编译,它没有触发,所以它似乎并不是不必要的冗长.

  • -Waggregate-return不是我认为是错误的东西.例如,它在类向量上使用基于范围的for循环时触发.返回值优化应该考虑到这种负面影响.

  • -Wconversion触发此代码:short n = 0; n += 2;隐式转换为int会导致警告,然后将其转换回其目标类型.

  • -Weffc++如果未在初始化程序列表中初始化所有数据成员,则包括警告.在很多情况下我故意不这样做,所以警告的集合太杂乱而无用.不过,偶尔打开一次并扫描其他警告(例如基类的非虚拟析构函数)是有帮助的.这将作为一组警告(如-Wall)而不是单独的警告更有用.

  • -Winline不存在是因为我没有使用inline关键字进行优化,只是为了在头文件中内联定义函数.我不在乎优化器是否实际内联它.如果它不能内联在类体(例如空虚拟析构函数)中声明的函数,则此警告也会抱怨.

  • -Winvalid-pch 因为我不使用预编译头文件而丢失.

  • -Wmissing-format-attribute没有使用因为我不使用gnu扩展名.同样的-Wsuggest-attribute和其他几个

  • 可能因缺席而引人注目的是-Wno-long-long,我没有必要这样做.我用-std=c++0x(-std=c++11在GCC 4.7中)编译,包括long long整数类型.那些停留在C++ 98/C++ 03上的人可能会考虑从警告列表中添加该排除.

  • -Wnormalized=nfc 已经是默认选项,看起来是最好的.

  • -Wpadded偶尔打开以优化类的布局,但它不会保留,因为并非所有类都有足够的元素来删除最后的填充.从理论上讲,我可以为"免费"获得一些额外的变量,但是不值得花费额外的努力(如果我的班级大小发生变化,那么删除那些以前的自由变量并不容易).

  • -Wstack-protector 不使用,因为我不使用 -fstack-protector

  • -Wstrict-aliasing=3被打开-Wall并且是最准确的,但它看起来像1级和2级提供更多警告.从理论上讲,较低的水平是一个"更强"的警告,但它的代价是更多的误报.我自己的测试代码在所有3个级别下干净地编译.

  • -Wswitch-enum不是我想要的行为.我不想明确处理每个switch语句.如果语言有一些机制来激活该指定开关语句这将是有益的(以确保未来枚举变化无处不在,他们需要处理的),但它是矫枉过正的"全有或全无"的设置.

  • -Wunsafe-loop-optimizations导致过多的虚假警告.定期应用此方法并手动验证结果可能很有用.例如,当我遍历向量中的所有元素以将一组函数应用于它们时(使用基于范围的for循环),它在我的代码中生成了此警告.它还警告const const std :: string的const数组的构造函数(其中这不是用户代码中的循环).

  • -Wzero-as-null-pointer-constant并且-Wuseless-cast是仅GCC-4.7警告,我将在转换到GCC 4.7时添加.

由于这项研究的结果,我已经在gcc上提交了一些错误报告/增强请求,所以希望我最终能够将"不包含"列表中的更多警告添加到"包含"列表中.此列表包含此主题中提到的所有警告(另外我还要考虑一些额外的警告).本文中未明确提及的许多警告都包含在我提到的另一个警告的一部分中.如果有人注意到完全被排除在此帖之外的任何警告,请告诉我.

编辑:看起来我错过了几个(我现在添加了).实际上http://gcc.gnu.org上的第二页很好地隐藏了.常规警告选项C++选项(向下滚动到警告的底部)

  • 顺便说一句 - 在你的“旧库代码”上使用 `-isystem` 而不是 `-I` 来防止所有这些误报 (2认同)

Sda*_*ons 37

噢,我的所有原始搜索都发布了99%关于如何抑制警告的帖子(非常可靠),但我只是遇到了这个评论,它有一套可爱的标志(一些不太相关):

交叉检查:

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

-g -O -Wall -Weffc++ -pedantic  \
-pedantic-errors -Wextra -Waggregate-return -Wcast-align \
-Wcast-qual -Wconversion \
-Wdisabled-optimization \
-Werror -Wfloat-equal -Wformat=2 \
-Wformat-nonliteral -Wformat-security  \
-Wformat-y2k \
-Wimplicit  -Wimport  -Winit-self  -Winline \
-Winvalid-pch   \
-Wlong-long \
-Wmissing-field-initializers -Wmissing-format-attribute   \
-Wmissing-include-dirs -Wmissing-noreturn \
-Wpacked  -Wpadded -Wpointer-arith \
-Wredundant-decls \
-Wshadow -Wstack-protector \
-Wstrict-aliasing=2 -Wswitch-default \
-Wswitch-enum \
-Wunreachable-code -Wunused \
-Wunused-parameter \
-Wvariadic-macros \
-Wwrite-strings
Run Code Online (Sandbox Code Playgroud)

所以,我认为这是一个很好的起点.没有意识到这是一个骗局,但至少它被埋没了.:-)

  • 从快速grep 4.5.2的c-opts.c/opts.c中获取'case OPT_W',你就错过了:strict overflow,undef,strict nul sentinel,normalized,multichar,implicit function declaration,deprecated,endif labels,评论**s**,内置宏重新定义,大于,大于eq,abi.很难找到列出它们的命令行选项. (3认同)
  • 我认为`-Wall`并不像人们所期望的那样做得更疯狂.但是谢谢你,其中一些看起来非常有用! (3认同)

Let*_*_Be 11

其中一些已经包含在-Wall或中-Wextra.

C的良好基础设置是:

-std=c99 -pedantic -Wall -Wextra -Wwrite-strings -Werror

对于C++

-ansi -pedantic -Wall -Wextra -Weffc++

(-Werror因为-Weffc++有一些烦恼而跳过C++ )

  • - 可以针对特定类型的警告禁用错误,例如:-Werror -Weffc ++ -Wno-error = effc ++ (10认同)
  • [ansi](https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#C-Dialect-Options):在 C 模式下,这相当于 `-std=c89`。在C++模式下,相当于`-std=c++98`。即,如果您指定其他“std”,请不要使用“ansi” (2认同)