47

What compiler warning level do you recommend for different C/C++ compilers?

gcc and g++ will let you get away with a lot on the default level. I find the best warning level for me is '-Wall'. And I always try to remove fix the code for the warnings it generates. (Even the silly ones about using parenthesis for logical precedence rules or to say I really mean 'if (x = y)')

What are your favorite levels for the different compilers, such as Sun CC, aCC (HPUX ?), Visual Studio, intel?

Edit:

I just wanted to point out that I don't use "-Werror" (but I do understand it's utility) on gcc/g++ because, I use:

#warning "this is a note to myself"

in a few places in my code. Do all the compilers understand the #warning macro?

4

14 回答 14

50

这是我用于 C++ 代码的一组额外的偏执标志:

    -g -O -Wall -Weffc++ -pedantic  \
    -pedantic-errors -Wextra -Waggregate-return -Wcast-align \
    -Wcast-qual  -Wchar-subscripts  -Wcomment -Wconversion \
    -Wdisabled-optimization \
    -Werror -Wfloat-equal  -Wformat  -Wformat=2 \
    -Wformat-nonliteral -Wformat-security  \
    -Wformat-y2k \
    -Wimplicit  -Wimport  -Winit-self  -Winline \
    -Winvalid-pch   \
    -Wunsafe-loop-optimizations  -Wlong-long -Wmissing-braces \
    -Wmissing-field-initializers -Wmissing-format-attribute   \
    -Wmissing-include-dirs -Wmissing-noreturn \
    -Wpacked  -Wpadded -Wparentheses  -Wpointer-arith \
    -Wredundant-decls -Wreturn-type \
    -Wsequence-point  -Wshadow -Wsign-compare  -Wstack-protector \
    -Wstrict-aliasing -Wstrict-aliasing=2 -Wswitch  -Wswitch-default \
    -Wswitch-enum -Wtrigraphs  -Wuninitialized \
    -Wunknown-pragmas  -Wunreachable-code -Wunused \
    -Wunused-function  -Wunused-label  -Wunused-parameter \
    -Wunused-value  -Wunused-variable  -Wvariadic-macros \
    -Wvolatile-register-var  -Wwrite-strings

这应该给你一些开始的东西。根据项目的不同,您可能需要将其调低,以免看到来自第三方库的警告(这些库通常对无警告非常粗心。)例如,Boost 向量/矩阵代码会使 g++ 发出很多的噪音。

处理这种情况的一种更好的方法是围绕 g++ 编写一个包装器,该包装器仍然使用调整到最大的警告,但允许人们禁止在特定文件/行号中看到它们。很久以前就写过这样的工具,等有时间清理一下再发布。

于 2008-12-30T19:47:49.107 回答
24

On Visual C++, I use /W4 and /WX (treat warnings as errors).

VC also has /Wall, but it's incompatible with the standard headers.

I choose to treat warnings as errors, because that forces me to fix them. I fix all warnings, even if that means adding #pragma to ignore the warning - that way, I'm stating explicitly, that I'm aware of the warning (so other developers won't e-mail me about it).

于 2008-12-30T09:32:20.127 回答
14

相信VC也支持

#pragma message ("note to self")

但是随着系统不断发展壮大,每晚构建 30 名开发人员同时工作,阅读所有笔记给自己需要几天时间,即使在这个数量上,自己只会阅读笔记并最终去在压力下无法跟上,不得不辞职……

不,如果你允许,警告的数量会迅速增加,而且你将无法发现真正重要的警告(未初始化的变量、构造函数中使用的 this 指针……)。

这就是我尝试将警告视为错误的原因:大多数情况下,编译器警告我是正确的,如果他不是,我将其记录在代码中并预先添加

#pragma warning ( push )
#pragma warning ( 4191 : disable )
// violent code, properly documented
#pragma warning ( pop )

刚读到他们也有warning ( N : suppress )编译指示。

于 2008-12-30T09:59:42.117 回答
10

I tend to use -Wall (because everyone does make bugs, nobody is perfect) , but i don't use -Werror (treat warnings as errors) because now and then gcc warns about things which are right anyway (false positives).

于 2008-12-30T09:24:43.123 回答
8

I agree with litb to always use -Wall. In addition, if you want to ensure your code is compliant you can also use -pedantic. Another warning that can be helpful if you're handling unions and structs at the byte level is -Wpadded.

于 2008-12-30T09:34:19.623 回答
4

我在打开错误时使用警告进行所有开发。

因为我仍然在 VC6 中开发,所以我的代码中有很多#pragma(主要是 4786)。

于 2008-12-30T11:04:38.273 回答
3

在 GCC 上,出于偏好,我使用-Wall -Wextra -Wwrite-strings -Werror,并使用std=. 哪个标准取决于项目:主要取决于它需要的可移植性。

我使用的原因-Werror是警告(对我来说)是不可接受的,即使它们并不代表真正的错误。我宁愿解决任何导致警告的问题,也不愿在我余生中每次编译时都忽略警告。一旦您在编译中允许警告,就很容易错过上次没有的警告。

当然,在处理第三方代码时,有时您无法摆脱警告。然后我会根据具体情况决定是否放宽-W选项,删除-Werror并编写脚本以检查是否只发生预期警告,或者修改第三方代码(“修复”警告或如果可能的话,用编译指示禁用它)。

于 2008-12-31T01:30:35.217 回答
3

no one has mentioned the Intel compiler yet:

https://software.intel.com/sites/products/documentation/doclib/iss/2013/compiler/cpp-lin/GUID-D060680A-1A18-4574-8291-5C74E6E31335.htm

-w3 is pretty chatty, so I would suggest -w2

于 2015-03-25T21:58:04.203 回答
3

我喜欢 -Wall 和严格的原型以及隐式函数定义。这些错误可能非常有用。还有 -Wextra 会收集各种各样的东西,比如你打算成为条件但不小心写成语句的东西:

if (something);
   classic_way_to_leak_memory();

在类 Unix 系统上,您必须遵守用户的 ENV 偏好 .. 所以他们看到和报告的内容可能与您需要的完全不同 :)

我也是一个类型双关语的恶魔,所以我也倾向于设置 -Fno-strict-aliasing ,除非用户想要它。否则,经典 C 中的安全内存管理很难实现。

于 2008-12-30T11:11:18.400 回答
3

这里有一个很好的 GCC 选项列表:http://mces.blogspot.com/2008/12/year-end-cleaning-ie-on-warning-options.htm。-Wall 不会启用所有可能的警告,有些警告必须明确启用。

于 2008-12-30T11:17:55.767 回答
1

在 Visual CI 中使用 /w3。我发现 w4 在每次构建时都会产生太多噪音(很多来自 MS 库)。额外的警告非常轻微,到目前为止还不是导致错误的原因。

于 2008-12-30T09:50:20.373 回答
1

我也喜欢检查在我的项目中给编译器的所有可能的警告。不幸的是,关于英特尔 C++编译器的回答对我来说不是很丰富(链接已失效)。我做了自己的研究。

因为我使用Qt 5qmake我有预定义的警告级别-w1。对此无能为力。但这还不是全部,ICC 有更多的键:

-Wcomment 
-Weffc++ 
-Wextra-tokens 
-Wformat 
-Winline // don't use, show only for example
-Wmain 
-Wmissing-declarations 
-Wmissing-prototypes 
-Wnon-virtual-dtor 
-Wp64 
-Wpointer-arith 
-Wremarks 
-Wreturn-type 
-Wsign-compare 
-Wstrict-aliasing 
-Wstrict-prototypes 
-Wtrigraphs 
-Wuninitialized 
-Wunknown-pragmas 
-Wunused-variable

更多关于所有的信息。

我还想补充一点,与 GCC 不同,ICC 会为一个键生成多个警告,例如 key -Weffc++。如果您只想看到所有列表中的几个警告,请使用 key -wd

我禁用:-wd1418,2012,2015,2017,2022,2013。并且警告-wd1572,873,2259,2261默认在 qmake 中被禁用。

我使用 PCH 并且发现在 Qt Creator 消息中看到关于使用 PCH 文件的错误非常烦人。要禁用,请使用-Wno-pch-messages

为了在代码中禁用警告,我使用:

#if defined(Q_CC_INTEL)
    #pragma warning( push )
    #pragma warning( disable: 2021 )
#endif

// some code

#if defined(Q_CC_INTEL)
    #pragma warning( pop )
#endif
于 2015-10-21T10:15:03.617 回答
0

感谢大家的回答。自从我使用除 gcc/g++ 之外的任何东西以来已经有一段时间了。我很久以前必须使用的是

-fmessage-length = 0(因为 g++ 有断行消息的丑陋习惯)

-Wno-deprecated(因为我在一个预先存在 std 命名空间的代码库上工作)

我确实记得(至少 5 年前)Sun Workshop CC 编译器默认警告级别之上的任何东西都太多了。我也认为这对于英特尔编译器来说可能是正确的。我已经有一段时间没有了解非 gnu 编译器了。

于 2008-12-30T17:34:37.673 回答
0

The GCC compilers become stricter with every new version. Use the flag -ansi to produce warnings for violations of the strictest interpretation of the ANSI language standards. That's usually stuff that just happens to work in your current compiler, but may produce errors in the next version or in other compilers. That flag will help you avoid having to port your code every time you switch compilers/versions.

于 2008-12-30T21:09:05.540 回答