【问题标题】:Best compiler warning level for C/C++ compilers? [closed]C/C++ 编译器的最佳编译器警告级别? [关闭]
【发布时间】:2010-09-28 19:54:03
【问题描述】:

对于不同的 C/C++ 编译器,您推荐什么编译器警告级别?

gcc 和 g++ 将让您在默认级别上摆脱很多。我发现对我来说最好的警告级别是“-Wall”。而且我总是尝试删除修复它生成的警告的代码。 (即使是关于将括号用于逻辑优先规则或说我的意思是“如果(x = y)”的愚蠢做法)

您最喜欢 Sun CC、aCC (HPUX ?)、Visual Studio、intel 等不同编译器的哪些级别?

编辑:

我只是想指出我不在 gcc/g++ 上使用“-Werror”(但我确实理解它的实用程序),因为我使用:

#warning “这是给我自己的便条”

在我的代码中的几个地方。所有的编译器都理解#warning 宏吗?

【问题讨论】:

  • #warning 是非标准的;不过,我认为#error 非常普遍

标签: c++ c warnings compiler-construction


【解决方案1】:

这是我用于 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++ 编写一个包装器,该包装器仍然使用调整到最大的警告,但允许人们禁止看到特定文件/行号的警告。很久以前就写过这么一个工具,等有时间清理一下再发布。

【讨论】:

  • 有人问了一个类似gcc-specific的问题,这个帖子被引用了。我更新了这个答案以删除重复的警告(例如,-Wformat=2 意味着 -Wformat-y2k)。见:stackoverflow.com/a/9862800/852254
  • g++ 不会使用 -Wimplicit 构建,是 C/ObjC 特定的。
  • 这里似乎有很多冗余。例如(至少在 GCC 上)-Wall implies -Wunused。另外,如果您解释了标志,这个答案会更好。
【解决方案2】:

在 Visual C++ 上,我使用 /W4/WX(将警告视为错误)。

VC也有/Wall,但与标准头文件不兼容。

我选择将警告视为错误,因为这迫使我修复它们。我修复了所有警告,即使这意味着添加 #pragma 以忽略警告 - 这样,我明确说明,我知道警告(因此其他开发人员不会通过电子邮件向我发送有关它的信息)。

【讨论】:

  • 我们有明确不注意的特定警告,以及其他所有内容的干净编译(无警告)政策。
【解决方案3】:

相信VC也支持

#pragma message ("note to self")

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

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

这就是我尝试将警告视为错误的原因:大多数时候,编译器是正确的警告我,如果他不是,我将其记录在代码中并放在前面

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

just read 他们也有 warning ( N : suppress ) 编译指示。

【讨论】:

    【解决方案4】:

    我倾向于使用-Wall(因为每个人都会犯错误,没有人是完美的),但我不使用-Werror(将警告视为错误),因为 gcc 时不时会警告无论如何都是正确的事情(误报)。

    【讨论】:

    • 那么,如果 gcc 向您抛出 100 条警告,您是否每次编译时都检查它们?否则,我看不出你是如何处理埋在一堆误报中的真正警告......
    • 您可以使用此处描述的技术解决 flex/bison 警告:wiki.services.openoffice.org/wiki/Writing_warning-free_code
    • Paulius,如果它向我抛出 100 条警告,我将修复这些警告,因此我只剩下一些警告,我不必担心。使用好的库可以避免出现警告信息页面。另外,codelogic 所说的。我有定期的“警告杀死”阶段,我会杀死它们:)
    • 我使用-W(又名-Wextra)和-Wall,因为它捕获了一些额外的警告,主要是由于拼写错误和忘记的代码路径(哎呀,忘了返回一些东西!)。这对于在编译阶段捕获愚蠢的错误非常有帮助。
    • 无论如何,我觉得最好启用所有警告,而不是只启用一些警告但启用 -Werror 只是因为否则将无法编译而不会出现错误。但这似乎是一个相当主观的事情:)
    【解决方案5】:

    我同意 litb 始终使用 -Wall。此外,如果你想确保你的代码是合规的,你也可以使用 -pedantic。如果您在字节级别处理联合和结构,另一个可能会有所帮助的警告是 -Wpadded。

    【讨论】:

      【解决方案6】:

      我在所有开发中都打开了警告作为错误。

      由于我仍在使用 VC6 进行开发,我的代码中有很多#pragma(主要是 4786)。

      【讨论】:

        【解决方案7】:

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

        【讨论】:

        【解决方案8】:

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

        if (something);
           classic_way_to_leak_memory();
        

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

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

        【讨论】:

          【解决方案9】:

          【讨论】:

            【解决方案10】:

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

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

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

            【讨论】:

              【解决方案11】:

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

              【讨论】:

                【解决方案12】:

                我也喜欢检查在我的项目中给编译器的所有可能的警告。不幸的是,关于 Intel 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
                

                更多关于keys

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

                【讨论】:

                  【解决方案13】:

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

                  -fmessage-length = 0(因为 g++ 有断行消息的丑陋习惯) -Wno-deprecated(因为我在一个预先存在 std 命名空间的代码库上工作)

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

                  【讨论】:

                    【解决方案14】:

                    每个新版本的 GCC 编译器都会变得更加严格。使用标志-ansi 来生成违反ANSI 语言标准最严格解释的警告。这通常是恰好在您当前的编译器中工作的东西,但可能会在下一个版本或其他编译器中产生错误。该标志将帮助您避免每次切换编译器/版本时都必须移植代码。

                    【讨论】:

                    • gcc -ansi 等价于 'gcc -std=c89';如果这是您想要的,那没关系,但如果您更喜欢 C99,请使用 '-std=c99'。
                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多