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

发布于 2024-10-18 22:37:56 字数 619 浏览 1 评论 0原文

通常,在 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++ 预编译了一组类似的完整警告标志? (我知道其中很多都是一样的。)

Often in C under gcc, I will start with the following set of warning flags (painfully assembled from multiple sources):

-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

I will build (at least my debug versions) with this set of warnings and fix everything I possibly can (usually everything), and then only remove flags if they are either not relevant or not fixable (almost never the case). Sometimes, I'll also add -Werror if I have to step away while compiling.

I'm just picking up C++ (yes, I'm 15 years behind the times), and I'd like to start off on the right foot.

My question is: Does someone have a precompiled similar set of complete warning flags for C++ under g++? (I know many of them will be the same.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

∞觅青森が 2024-10-25 22:37:56

我浏览了一下,发现应该得到最高级别警告的最小包含集。然后,我从该列表中删除了一组警告,我认为这些警告实际上并不表明正在发生不良情况,或者有太多误报无法在实际构建中使用。我评论了为什么我排除的每个人都被排除在外。这是我最后一组建议警告:

-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogic-op -Wmissing -声明 -Wmissing-include-dirs -Wno except -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
    常量表达式)
    ,该结果被隐式提升为 int。它
    如果您将该值分配给,则警告潜在的符号问题
    unsignedunsigned short,即使它是安全的。这是
    对于几乎所有用户来说绝对是最可选的警告。

  • -Wsign-promo:请参阅 -Wsign-conversion

  • -Wswitch-default 似乎毫无意义(你并不总是想要默认值
    如果您已明确列举了所有可能性,则为这种情况)。然而,
    打开这个警告可以强制执行一些可能是好的事情
    主意。对于您明确想要忽略除以下所有内容的情况
    列出的可能性(但其他数字也是可能的),然后输入
    default: break; 中使其明确。如果你显式枚举
    所有可能性,然后打开此警告将有助于确保
    你放了像断言(假)这样的东西来确保你已经
    实际上涵盖了所有可能的选择。它可以让你明确地
    你的问题的范围是什么,并以编程方式强制执行。
    然而,你必须小心坚持断言(假)
    到处。这比默认情况下什么都不做要好,但是
    与通常的断言一样,它在发布版本中不起作用。在其他方面
    换句话说,你不能依赖它来验证你得到的数字,
    例如,您没有绝对的网络连接或数据库
    控制。例外或提前返回是最好的方法
    处理这个问题(但仍然要求你有一个默认情况!)。

  • -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 进行编译(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 数组的构造函数(其中 this 不是
    用户代码中的循环)。

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

作为一些研究的结果,我已经向 gcc 提交了一些错误报告/增强请求,因此希望我最终能够将更多警告从“不包括”列表添加到“包括”列表。该列表包括该线程中提到的所有警告(加上我认为一些额外的警告)。本文中未明确提及的许多警告已作为我提到的另一个警告的一部分包含在内。如果有人注意到本文完全排除了任何警告,请告诉我。

编辑:看起来我错过了几个(我现在已经添加了)。实际上,http://gcc.gnu.org 上还有一个隐藏得很好的页面。 一般警告选项C++ 选项(向下滚动到底部查看警告)

I went through and found the minimal set of includes that should get the maximum level of warning. I then removed from that list the set of warnings that I feel do not actually indicate something bad is happening, or else have too many false positives to be used in a real build. I commented as to why each of the ones I excluded were excluded. This is my final set of suggested warnings:

-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

Questionable warnings that are present:

  • I include -Wno-unused because I often have variables that I know I
    will use later, but do not yet have the functionality written for.
    Removing warnings about that allows me to write in my preferred style
    of occasionally deferring the implementation of things. It is useful
    to turn that off every once in a while to make sure nothing slipped
    through the cracks.

  • -Wdisabled-optimization seems like a strong user-preference
    setting. I just added this one to my build (only for optimized builds
    for obvious reasons) and it didn't turn anything up, so it doesn't
    seem to be an especially chatty warning, at least for the way I code.
    I include it (even though code that triggers this warning isn't
    necessarily wrong) because I believe in working with my tools instead
    of against them. If gcc is telling me that it cannot optimize code
    for the way I wrote it, then I should look at rewriting it. I suspect
    that code that triggers this warning could benefit from being more
    modular, regardless, so although the code is not technically wrong
    (probably), stylistically it likely is.

  • -Wfloat-equal warns for safe equality comparisons (in particular,
    comparison with a non-computed value of -1). An example in my code
    where I use this is that I have a vector of float. I go through this
    vector, and there are some elements I cannot evaluate yet what they
    should be, so I set them to -1.0f (since my problem only uses
    positive numbers, -1 is out of the domain). I later go through and
    update -1.0f values. It does not easily lend itself to a different
    method of operation. I suspect that most people don't have this
    problem, and comparison of an exact number in floating point is
    probably an error, so I'm including it in the default list.

  • -Wold-style-cast has a lot of false positives in library code I'm using. In particular, the htonl family of functions used in networking, as well as a Rijndael (AES) encryption implementation I'm using has old-style casts that it warns me about. I intend to replace both of these, but I'm not sure if there is anything else in my code that it will complain about. Most users should probably have this on by default, though.

  • -Wsign-conversion was a tough one (and almost didn't make the
    list). Turning it on in my code generated a huge amount of warnings
    (100+). Almost all of them were innocent. However, I have been
    careful to use signed integers wherever I wasn't sure, although for
    my particular problem domain, I would usually get a slight efficiency
    increase using unsigned values due to the large amount of integer
    division I do. I sacrificed this efficiency because I was concerned
    about accidentally promoting a signed integer to an unsigned and then
    dividing (which is not safe, unlike addition, subtraction, and
    multiplication). Turning on this warning allowed me to safely change
    most of my variables to unsigned types and add a few casts in some
    other places. It's currently a little hard to use because the warning
    isn't that smart. For instance, if you do unsigned short + (integral
    constant expression)
    , that result is implicitly promoted to int. It
    then warns about a potential sign problem if you assign that value to
    unsigned or unsigned short, even though it's safe. This is
    definitely the most optional warning for almost all users.

  • -Wsign-promo: see -Wsign-conversion.

  • -Wswitch-default seems pointless (you don't always want a default
    case if you've enumerated all possibilities explicitly). However,
    turning on this warning can enforce something that is probably a good
    idea. For cases where you explicitly want to ignore everything except
    the listed possibilities (but other numbers are possible), then put
    in default: break; to make it explicit. If you explicitly enumerate
    all possibilities, then turning on this warning will help ensure that
    you put something like assert (false) to make sure that you've
    actually covered all possible options. It lets you be explicit in
    what the domain of your problem is and programatically enforces that.
    However, you'll have to be careful in just sticking assert (false)
    everywhere. It's better than doing nothing with the default case, but
    as usual with assert, it won't work in release builds. In other
    words, you cannot rely on it to validate numbers that you get from,
    say, a network connection or a database that you do not have absolute
    control over. Exceptions or returning early are the best way to
    handle that (but still require you to have a default case!).

  • -Werror is an important one for me. When compiling large amounts of
    code in a multi-threaded build with multiple targets, it's easy for a
    warning to slip by. Turning warnings into errors ensures that I
    notice them.

Then there is a set of warnings that are not included in the above list because I did not find them to be useful. These are the warnings and my comments on why I'm not including them in the default list:

Warnings that are absent:

  • -Wabi is not needed because I'm not combining binaries from different compilers. I tried compiling with it anyway, and it didn't trigger, so it doesn't seem needlessly verbose.

  • -Waggregate-return is not something that I consider an error. For
    instance, it triggers when using a range-based for loop on a vector
    of classes. Return value optimization should take care of any
    negative effects of this.

  • -Wconversion triggers on this code: short n = 0; n += 2; The
    implicit conversion to int causes a warning when it's then converted
    back to its target type.

  • -Weffc++ includes a warning if all data members are not initialized
    in the initializer list. I intentionally do not do this in many
    cases, so the set of warnings is too cluttered to be useful. It's
    helpful to turn on every once in a while and scan for other warnings,
    though (such as non-virtual destructors of base classes). This would
    be more useful as a collection of warnings (like -Wall) instead of
    a single warning on its own.

  • -Winline is absent because I don't use the inline keyword for
    optimization purposes, just to define functions inline in headers. I
    don't care if the optimizer actually inlines it. This warning also
    complains if it can't inline a function declared in a class body
    (such as an empty virtual destructor).

  • -Winvalid-pch is missing because I don't use precompiled headers.

  • -Wmissing-format-attribute is not used because I do not use gnu
    extensions. Same for -Wsuggest-attribute and several others

  • Potentially notable for its absence is -Wno-long-long, which I have
    no need for. I compile with -std=c++0x (-std=c++11 in GCC 4.7),
    which includes long long integer types. Those stuck back on C++98 /
    C++03 may consider adding that exclusion from the warning list.

  • -Wnormalized=nfc is already the default option, and looks to be the
    best.

  • -Wpadded is turned on occasionally to optimize the layout of
    classes, but it is not left on because not all classes have enough
    elements to remove padding at the end. In theory I could get some
    extra variables for 'free', but it's not worth the extra effort of
    maintaining that (if my class size changes, it's not easy to remove
    those previously free variables).

  • -Wstack-protector is not used because I do not use -fstack-protector

  • -Wstrict-aliasing=3 is turned on by -Wall and is the most
    accurate, but it looks like level 1 and 2 give more warnings. In
    theory a lower level is a 'stronger' warning, but it's at the cost of
    more false positives. My own test code compiled cleanly under all 3
    levels.

  • -Wswitch-enum isn't behavior that I want. I don't want to handle
    every switch statement explicitly. It would be useful if the language
    had some mechanism to activate this on specified switch statements
    (to ensure that future changes to the enum are handled everywhere
    that they need to be), but it's overkill for an "all-or-nothing"
    setting.

  • -Wunsafe-loop-optimizations causes too many spurious warnings. It
    may be useful to apply this one periodically and manually verify the
    results. As an example, it generated this warning in my code when I
    looped over all elements in a vector to apply a set of functions to
    them (using the range-based for loop). It is also warning for the
    constructor of a const array of const std::string (where this is no
    loop in user code).

  • -Wzero-as-null-pointer-constant and -Wuseless-cast are
    GCC-4.7-only warnings, which I will add when I transition to GCC 4.7.

I've filed a few bug reports / enhancement requests at gcc as a result of some of this research, so hopefully I'll be able to eventually add more of the warnings from the "do not include" list to the "include" list. This list includes all warnings mentioned in this thread (plus I think a few extra). Many of the warnings not explicitly mentioned in this post are included as part of another warning I do mention. If anyone notices any warnings that are excluded from this post entirely, let me know.

edit: It looks like I had missed several (which I have now added in). There is actually a second page at http://gcc.gnu.org that is quite well hidden. General warning options and C++ options (scroll down to the bottom for warnings)

我偏爱纯白色 2024-10-25 22:37:56

天啊,我所有的原始搜索都找到了 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

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

D'oh, all of my original searches turned up 99% of posts on how to suppress warnings (scarily enough), but I just ran across this comment, which has this lovely set of flags (some less relevant):

Cross checked with:

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

So, I think that's a good starting point. Didn't realize this was a dupe, but at least it was deeply buried. :-)

梦开始←不甜 2024-10-25 22:37:56

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

C 的良好基本设置是:

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

和 C++

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

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

Some of those are already included in -Wall or -Wextra.

A good base setup for C is:

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

and for C++

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

(skipping -Werror for C++ since -Weffc++ has some annoyances)

把人绕傻吧 2024-10-25 22:37:56

尝试

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

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

另一件事是我在 -Werror 中添加了这一点,因为如果您不修复警告,为什么要关心打开它们呢?您还可以从列表中删除警告。 (例如,我几乎从不在 C++ 中使用 -Waggregate-return。)

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

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

Try

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

That's a quick and dirty start which will definitely need some tuning; for one thing, even if you call the compiler by the appropriate name for your language (e.g. g++ for C++), you will get warnings that don't apply to that language (and the compiler will throw up its hands and refuse to continue until you remove the warning).

Another thing is that I added in -Werror, because if you aren't fixing the warnings, why do you care about turning them on? You can also take warnings out of the list. (For example, I almost never use -Waggregate-return with C++.)

Some warnings won't do anything without other performance related options (-Wstack-protector). -fdiagnostics-show-option and the GCC manual are your friends.

By the way, some warnings are mutually exclusive; in particular using -Wtraditional and -Wold-style-definition along with -Werror, will not compile.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文