3 回答
TA贡献1982条经验 获得超2个赞
我仔细研究了一下,发现应该包含最高警告级别的最小包含集。然后,我从该列表中删除了一些警告,这些警告我认为实际上并没有表明正在发生不良情况,或者有太多的误报无法在实际版本中使用。我评论了为什么我排除的每个人都被排除在外。这是我最后建议的警告集:
-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。如果您将该值分配给unsigned
或unsigned short
,即使它是安全的,它也会警告潜在的标志问题 。对于几乎所有用户,这绝对是最可选的警告。-Wsign-promo
:参见-Wsign-conversion
。-Wswitch-default
似乎毫无意义(如果您已经明确列举了所有可能性,则不必总是想要默认情况)。但是,打开此警告可能会强制执行某些操作,这可能是个好主意。如果您明确想忽略除所列可能性之外的所有内容(但其他数字也是可能的),请输入default: break;
使其明确。如果你明确地列举所有的可能性,然后打开该警告将有助于确保你把东西像断言(假),以确保您实际上已经涵盖了所有可能的选项。它可以让你在你的问题域是明确和编程强制执行。但是,你必须要在短短坚持断言(假)到处小心。这比对默认情况不执行任何操作要好,但是与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语句。如果该语言具有某种机制来激活指定的switch语句(以确保将来需要对枚举进行的更改可以在需要处理的所有地方进行处理),则将很有用,但是对于“全有或全无”设置而言,这是过分的。-Wunsafe-loop-optimizations
导致太多虚假警告。定期应用此方法并手动验证结果可能会很有用。例如,当我遍历向量中的所有元素以向它们应用一组功能时(使用基于范围的for循环),它在我的代码中生成了此警告。它也用于警告常量性病的一个const阵列的构造::串(这里,这是在用户代码没有循环)。-Wzero-as-null-pointer-constant
并且-Wuseless-cast
是仅限GCC-4.7的警告,我将在过渡到GCC 4.7时添加这些警告。
由于这项研究,我已在gcc上提交了一些错误报告/增强功能请求,因此希望最终我能够将更多的警告从“不包括”列表添加到“包含”列表中。该列表包括该线程中提到的所有警告(另外,我认为还有一些警告)。我没有提到的另一个警告中包含了本文中未明确提及的许多警告。如果有人发现本帖子完全排除的任何警告,请告诉我。
编辑:好像我错过了几个(现在我已经添加了)。实际上,http://gcc.gnu.org上有第二个页面,该页面非常隐蔽。常规警告选项和C ++选项(向下滚动至警告底部)
TA贡献1851条经验 获得超3个赞
尝试
export CFLAGS="`gcc --help=warnings | grep '\-W' | awk '{print $1 \" \"}' |
sort | uniq` -pedantic -fdiagnostics-show-option -Werror"
这是一个快速而肮脏的开始,肯定需要进行一些调整。一方面,即使您使用与您的语言相对应的名称来调用编译器(例如,g++对于C ++),您也会收到不适用于该语言的警告(并且编译器会举手并拒绝继续操作,直到您删除警告)。
另一件事是我添加的-Werror,因为如果您不修正警告,那么为什么还要关心开启它们呢?您也可以从列表中删除警告。(例如,我几乎从不使用-Waggregate-returnC ++。)
如果没有其他与性能相关的选项(-Wstack-protector),某些警告将无法执行任何操作。-fdiagnostics-show-option和GCC手册是您的朋友。
顺便说一句,有些警告是互斥的。特别是-Wtraditional和-Wold-style-definition一起使用时-Werror,将无法编译。
- 3 回答
- 0 关注
- 859 浏览
添加回答
举报