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

时间:2011-02-23 08:20:07

标签: c++ g++ warnings

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

-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

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

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

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

5 个答案:

答案 0 :(得分:117)

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

-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)进行比较。我的代码中的一个例子 我使用的地方是我有一个浮动向量。我经历了这个 矢量,还有一些我无法评估它们的元素 应该是,所以我把它们设置为-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;中使其明确。如果你明确枚举 所有可能性,然后打开此警告将有助于确保 你把断言(假)这样的东西确定为你 实际涵盖了所有可能的选择它让你明确 你的问题的领域是什么,并以编程方式强制执行。 但是,你必须小心坚持断言(假) 到处。它比默认情况下无所作为更好,但是 像断言一样,它不会在发布版本中工作。其他 单词,你不能依靠它来验证你得到的数字, 比如,网络连接或您没有绝对的数据库 掌控。例外或早退是最好的方法 处理(但仍然要求你有一个默认情况!)。

  • -Werror对我来说非常重要。编译大量时 在具有多个目标的多线程构建中的代码,对于a来说很容易 警告滑倒。将警告转为错误可确保我 注意他们。

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

缺席的警告:

  • -Wabi不需要,因为我没有组合来自不同编译器的二进制文件。无论如何,我尝试用它进行编译,但它并没有触发,所以它看起来并不那么冗长。

  • -Waggregate-return不是我认为是错误的东西。对于 例如,它在向量上使用基于范围的for循环时触发 课程。返回值优化应该照顾任何 这种负面影响。

  • -Wconversion触发此代码:short n = 0; n += 2; 隐式转换为int会在转换后发出警告 回到目标类型。

  • 如果未初始化所有数据成员,则
  • -Weffc++会包含警告 在初始化列表中。我故意不要在很多方面这样做 因此,一组警告太杂乱而无用。它' S 有帮助每隔一段时间打开一次并扫描其他警告, 虽然(例如基类的非虚拟析构函数)。这个会 作为一组警告(如-Wall)而不是更有用 单独发出警告。

  • -Winline缺席,因为我没有使用inline关键字 优化目的,只是在标题中定义内联函数。一世 如果优化器实际内联它,请不要关心它。这个警告也 抱怨如果它不能内联在类体中声明的函数 (例如空虚拟析构函数)。

  • -Winvalid-pch丢失,因为我没有使用预编译的标头。

  • -Wmissing-format-attribute未使用,因为我不使用gnu 扩展。 -Wsuggest-attribute和其他几个

  • 相同
  • 潜在值得注意的是它的缺席-Wno-long-long,我有 没必要。我使用-std=c++0x(GCC 4.7中的-std=c++11)编译, 其中包括long long个整数类型。那些坚持使用C ++ 98 / C ++ 03可能会考虑从警告列表中添加该排除。

  • -Wnormalized=nfc已经是默认选项,并且看起来像是 最好的。

  • 偶尔打开
  • -Wpadded来优化布局 类,但它没有留下,因为并非所有类都足够 用于删除末尾填充的元素。从理论上讲,我可以得到一些 “免费”的额外变量,但它不值得付出额外的努力 保持这一点(如果我的班级规模发生变化,则不容易删除 那些以前的自由变量)。

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

  • -Wstrict-aliasing=3-Wall启用,是最多的 准确,但看起来1级和2级给出更多警告。在 理论,较低的水平是一个更强大的'警告,但这是以牺牲为代价的 更多的误报。我自己的测试代码在所有3下完全编译 水平。

  • -Wswitch-enum不是我想要的行为。我不想处理 每个switch语句都明确。如果语言会很有用 有一些机制可以在指定的switch语句上激活它 (以确保将来处理枚举的未来更改 他们需要这样做,但对于“全有或全无”而言,这是过度的。 设置。

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

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

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

编辑:好像我错过了几个(我现在添加了)。实际上http://gcc.gnu.org的第二页很好地隐藏了。 General warning optionsC++ options (scroll down to the bottom for warnings)

答案 1 :(得分:35)

噢,我的所有原始搜索都发现99%的帖子关于如何压制警告(非常可怕),但我只是跑过this comment,这有可爱一组标志(一些不太相关):

交叉检查:

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

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

答案 2 :(得分:11)

其中一些已包含在-Wall-Wextra

C的良好基础设置是:

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

和C ++

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

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

答案 3 :(得分:2)

尝试

export CFLAGS="`gcc --help=warnings | grep '\-W' | awk '{print $1 \" \"}' |
sort | uniq` -pedantic -fdiagnostics-show-option -Werror"

这是一个快速而又肮脏的开始,肯定需要一些调整;首先,即使您使用适合您的语言的名称调用编译器(例如,对于C ++来说是g++),您将收到不适用于该语言的警告(并且编译器会抛弃它并且拒绝继续,直到你删除警告)。

另一件事是我添加了-Werror,因为如果您没有修复警告,为什么还要关心它们?您也可以从列表中取出警告。 (例如,我几乎从不使用-Waggregate-return和C ++。)

如果没有其他与性能相关的选项(-Wstack-protector),某些警告将无法执行任何操作。 -fdiagnostics-show-option和GCC手册是您的朋友。

顺便说一下,有些警告是相互排斥的;特别是使用-Wtraditional-Wold-style-definition以及-Werror,将无法编译。

答案 4 :(得分:0)

在我的Clion的CmakeLists.txt中

cmake_minimum_required(VERSION 3.13)
project(cpp17)

set(CMAKE_CXX_STANDARD 17)

set(GCC_COVERAGE_COMPILE_FLAGS "-std=c++17 -Wall -Weffc++ -Wno-error=effc++ -pedantic \
 -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-newline-eof  \
-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")


set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )

add_executable(cpp17 main.cpp)