我想启用GCC拥有的所有警告。(你会认为这很容易…)

你可能会想-墙可能会管用,但不是!你还需要-沃特。 你可能会想-Wextra可能会奏效,但不是!并不是这里列出的所有警告(例如,-Wshadow)都可以通过此命令启用。我仍然不知道这个列表是否全面。

我如何告诉GCC启用(没有if's, and's, or but's!)它所具有的所有警告?


当前回答

GCC 4.3+现在有-Q——help=警告,你甚至可以指定——help=警告,打印出与C相关的警告。

我刚刚写了一个m4模块来利用这一点(它也支持Clang的-Weverything);看到wget_manywarnings.m4。

如何使用它很简单。基本上,模块会打开每个警告标志。您还可以根据需要删除警告—有些警告非常冗长。

例如:configure.ac

如果你不使用autotools,你会发现在m4模块中打开所有禁用警告的代码,这基本上是通过AWK管道的GCC调用:

旗帜= " - wall -Wextra -Wformat = 2”$ (gcc - wall -Wextra -Wformat = 2 q——帮助=警告,C | awk '{如果(($ 2 = =“(残疾人)”| | 2美元 == "") && $ 1 !~/=/ && $1~/^-W/&& $1!="-Wall") print $1} `

其他回答

你不能。

GCC 4.4.0的手册只是该版本的综合手册,但它确实列出了4.4.0所有可能的警告。不过,它们并不都在你链接的页面上。例如,c++选项或Objective-C选项页面上有一些特定于语言的选项。要找到所有选项,最好查看选项摘要

打开所有选项将包括-Wdouble-promotion,它只与带有32位单精度浮点单元的cpu相关,该单元在硬件中实现浮点运算,但在软件中模拟double。以double方式进行计算将使用软件模拟,并且速度较慢。这与某些嵌入式cpu有关,但与硬件支持64位浮点的现代桌面cpu完全无关。

另一个通常不常用的警告是-Wtraditional,它警告在传统C中具有不同含义(或不起作用)的完美格式的代码,例如“字符串”“连接”或ISO C函数定义!你真的关心与30年前的编译器的兼容性吗?你真的想要一个写int inc(int i) {return i+1的警告吗?} ?

I think -Weffc++ is too noisy to be useful. It's based on the outdated first edition of Effective C++ and warns about constructs which are perfectly valid C++ (and for which the guidelines changed in later editions of the book). I don't want to be warned that I haven't initialized a std::string member in my constructor; it has a default constructor that does exactly what I want. Why should I write m_str() to call it? The -Weffc++ warnings that would be helpful are too difficult for the compiler to detect accurately (giving false negatives), and the ones that aren't useful, such as initializing all members explicitly, just produce too much noise, giving false positives.

Luc Danton提供了一个来自-Waggregate-return的无用警告的好例子,几乎可以肯定,这些警告对c++代码毫无意义。

也就是说,你并不需要所有的警告;你只是觉得你知道。

通读手册,阅读它们,决定您可能想要启用哪些,并尝试它们。无论如何,阅读编译器的手册是一个好东西,走捷径并启用你不理解的警告不是一个很好的主意,特别是如果它是为了避免不得不RTFM。

那些把所有东西都打开的人,可能要么是因为他们毫无头绪,要么是因为一头尖尖头发的老板说“没有警告”。

有些警告很重要,有些则不然。你必须有辨别力,否则你的程序就会一团糟。以-Wdouble-promotion为例。如果你在嵌入式系统上工作,你可能需要这个;如果您使用的是桌面系统,则可能不需要。你想要- wtradition吗?我对此表示怀疑。

参见-Wall-all启用所有警告,关闭为WONTFIX。

DevSolar抱怨makefile需要根据编译器版本使用不同的警告,如果-Wall -Wextra不适合,那么使用特定于编译器和特定于版本的CFLAGS并不困难:

compiler_name := $(notdir $(CC))
ifeq ($(compiler_name),gcc)
compiler_version := $(basename $(shell $(CC) -dumpversion))
endif
ifeq ($(compile_name),clang)
compiler_version := $(shell $(CC) --version | awk 'NR==1{print $$3}')
endif
# ...
wflags.gcc.base := -Wall -Wextra
wflags.gcc.4.7 := -Wzero-as-null-pointer-constant
wflags.gcc.4.8 := $(wflags.gcc.4.7)
wflags.clang.base := -Wall -Wextra
wflags.clang.3.2 := -Weverything
CFLAGS += $(wflags.$(compiler_name).base) $(wflags.$(compiler_name).$(compiler_version))

EDIT 2023:为GCC 12刷新。


我从其他帖子中收集了信息,并逐个测试了c++库测试中的警告。

使用Haatschii的列表和他/她获得GCC 11完整列表的方法:

gcc -Wall -Wextra -Wpedantic -Q --help=warning

在所有这些警告中,有些并不适用于c++,所以这里列出了一些警告和一些适用于我的c++项目测试的最小注释。

考虑到:

其中一些警告在默认情况下已经开启,无需添加任何选项。 我不敢说我知道一些警告的真正含义。 我不建议使用或不使用任何特定的警告。 有些是评论,但那并不意味着什么。根据需要对它们进行注释或取消注释。(我评论了那些对我的项目没有用处的。) 有些将不能在GCC 10上工作。 该列表是按原样给出的,它可能包含错误或拼写错误。

这个列表基本上是按字母顺序排列的,为了节省垂直空间,有一些最小的聚类。作为奖励,它被格式化用于CMake项目。

下面是清单:

target_compile_options(
    target
    PRIVATE
        $<$<AND:$<CXX_COMPILER_ID:GNU>,$<NOT:$<CUDA_COMPILER_ID:NVIDIA>>,$<NOT:$<CUDA_COMPILER_ID:Clang>>>:
            -Werror
            -Wall
            -Wextra  # (activates -Wunknown-pragmas)
            -Wpedantic
            -WNSObject-attribute  # (gcc 12, not in 11)
            # -Wabi=13 -Wabi-tag (maybe important when linking with very old libraries)
            # -Wabsolute-value  # C/ObjC only (gcc 12, not in 11)
            -Waddress
            # -Waddress-of-packed-member (gcc 11, not in gcc 8)
            # -Waggregate-return (disallow return classes or structs, seems a C-compatibility warning)
            -Waggressive-loop-optimizations
            # -Waligned-new=all  (gcc 12, not in 11)
            # -Walloc-size-larger-than=<bytes>  (gcc 12, not in 11)
            -Walloc-zero  # -Walloc-size-larger-than=<bytes>
            -Walloca  # -Walloca-larger-than=<number>
            # -Wanalyzer-double-fclose -Wanalyzer-double-free -Wanalyzer-exposure-through-output-file -Wanalyzer-file-leak -Wanalyzer-free-of-non-heap -Wanalyzer-malloc-leak (gcc 11, not in gcc 9)
            # -Wanalyzer-mismatching-deallocation (gcc 11, not in gcc 10)
            # -Wanalyzer-null-argument -Wanalyzer-possible-null-argument -Wanalyzer-null-dereference (gcc 11, not in gcc 9)
            # -Wanalyzer-possible-null-dereference (gcc 11, not in gcc 9)
            # -Wanalyzer-shift-count-negative -Wanalyzer-shift-count-overflow (gcc 11, not in gcc 10)
            # -Wanalyzer-stale-setjmp-buffer
            # -Wanalyzer-tainted-allocation-size (gcc 12, not in 11)
            # -Wanalyzer-tainted-array-index (gcc 11, not in gcc 9)
            # -Wanalyzer-tainted-divisor -Wanalyzer-tainted-offset -Wanalyzer-tainted-size -Wanalyzer-too-complex -Wanalyzer-unsafe-call-within-signal-handler (gcc 12, not in 11)
            # -Wanalyzer-unsafe-call-within-signal-handler -Wanalyzer-use-after-free -Wanalyzer-use-of-pointer-in-stale-stack-frame
            # -Wanalyzer-write-to-const -Wanalyzer-write-to-string-literal (gcc 11, not in gcc 10)
            # -Warith-conversion (gcc 11, not in gcc 9)
            -Warray-bounds
            # -Warray-bounds=<0,2> -Warray-compare (gcc 12, not in gcc 9)
            # -Warray-parameter -Warray-parameter=<0,2>  (gcc 11, not in gcc 10)
            # -Wattribute-alias -Wattribute-alias=<0,2> (gcc 12, not in 11)
            # -Wattribute-warning (gcc 9, not in 8)
            -Wattributes
            # -Wbad-function-cast (gcc 12, not in 11)
            -Wbool-compare -Wbool-operation
            # -Wbidi-chars -Wbidi-chars=any (gcc 12, not in 11)
            -Wbuiltin-declaration-mismatch -Wbuiltin-macro-redefined
            #-Wc++-compat
            -Wc++0x-compat -Wc++11-compat -Wc++14-compat -Wc++17-compat -Wc++17-extensions -Wc++1z-compat
            # -Wc++20-compat -Wc++20-extensions -Wc++23-extensions -Wc++2a-compat (gcc 11, not in gcc 9)
            # -Wcannot-profile (gcc 9, not in gcc 8)
            -Wcast-align=strict -Wcast-function-type
            -Wcast-qual
            -Wcatch-value  #=<0, 3>
            -Wchar-subscripts
            # -Wchkp -Wclass-conversion -Wclass-memaccess (gcc 12, not in 11)
            # -Wclobbered
            # -Wcomma-subscript (gcc 12, not in 11)
            # -Wcomment  # (same as -Wcomments)
            # -Wcompare-reals (gcc 12, not in 11)
            -Wconditionally-supported
            -Wconversion -Wconversion-null
            -Wcoverage-mismatch -Wcpp
            # -Wctad-maybe-unsupported  # TODO(correaa) add ctad explicitly as necessary
            -Wctor-dtor-privacy
            -Wdangling-else
            # -Wdangling-pointer (gcc 12, not in 11)
            -Wdate-time
            # -Wdeclaration-after-statement (gcc 12, not in 11)
            -Wdelete-incomplete -Wdelete-non-virtual-dtor
            -Wdeprecated
            # -Wdeprecated-copy -Wdeprecated-copy-dtor (gcc 11, not in gcc 8)
            -Wdeprecated-declarations
            # -Wdeprecated-enum-enum-conversion -Wdeprecated-enum-float-conversion (gcc 11, not in gcc 10)
            # -Wdesignated-init (gcc 12, not in 11)
            -Wdisabled-optimization
            # -Wdiscarded-array-qualifiers (gcc 12, not in 11)
            -Wdiv-by-zero -Wdouble-promotion
            # -Wduplicate-decl-specifier (gcc 12, not in 11)
            -Wduplicated-branches -Wduplicated-cond
            # -Weffc++ (doesn't allow some advanced techniques, such as CRTP)
            -Wempty-body -Wendif-labels
            -Wenum-compare
            # -Wenum-conversion (gcc 11, not in gcc 10)
            -Wexpansion-to-defined
            # -Werror-implicit-function-declaration not for C++ (gcc 12, not in 11)
            # -Wexceptions  (gcc 11, not in gcc 10)
            # -Wextra
            -Wextra-semi
            -Wfloat-conversion # -Wfloat-equal (disallows float equality)
            -Wformat=2
            # -Wformat-contains-nul (gcc 12, not in 11)
            # -Wformat-diag (gcc 10, not in gcc 9)
            -Wformat-extra-args -Wformat-nonliteral
            # -Wformat-overflow=1
            -Wformat-security -Wformat-signedness -Wformat-truncation -Wformat-y2k -Wformat-zero-length
            -Wframe-address  # -Wframe-larger-than=<byte-size>
            -Wfree-nonheap-object -Whsa
            -Wif-not-aligned
            -Wignored-attributes -Wignored-qualifiers
            # -Wimplicit (gcc 12, not in 11)
            -Wimplicit-fallthrough#=3  # -Wimplicit-fallthrough=<0,5>
            # -Wimplicit-function-declaration -Wimplicit-int (gcc 12, not in 11)
            # -Winaccessible-base (gcc 12, not in 11)
            # -Wincompatible-pointer-types -Winfinite-recursion  -Winherited-variadic-ctor -Winit-list-lifetime (gcc 12, not in 11)
            -Winit-self
            # -Winline
            # -Wint-conversion (gcc 12, not in 11)
            -Wint-in-bool-context -Wint-to-pointer-cast
            # -Winterference-size (gcc 12, not in 11)
            # -Winvalid-imported-macros (gcc 11, not in gcc 10)
            -Winvalid-memory-model -Winvalid-offsetof -Winvalid-pch
            # -Wjump-misses-init (gcc 12, not in 11)
            # -Wlarger-than=<byte-size>  # (disallow large objects types? in executable)
            -Wliteral-suffix
            -Wlogical-not-parentheses -Wlogical-op
            # -Wlong-long (C++98 warning)
            -Wlto-type-mismatch -Wmain -Wmaybe-uninitialized
            -Wmemset-elt-size -Wmemset-transposed-args
            -Wmisleading-indentation
            # -Wmismatched-dealloc -Wmismatched-new-delete (gcc 11, not in gcc 10)
            # -Wmismatched-tags (gcc 11, not in gcc 9)
            -Wmissing-attributes
            -Wmissing-braces -Wmissing-declarations -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn
            # -Wmissing-parameter-type (gcc 12, not in  11)
            # -Wmissing-profile (gcc 11, not in gcc 8)
            # -Wmissing-prototypes -Wmissing-requires -Wmissing-template-keyword (gcc 12, not in 11)
            -Wmultichar
            # -Wmultiple-inheritance (disallows composition by inheritance)
            -Wmultistatement-macros
            # -Wnamespaces (disallows use of namespaces, seems a C-tool)
            -Wnarrowing
            # -Wnested-externs (gcc 12, not in 11)
            # -Wno-alloc-size-larger-than=<bytes> -Wframe-larger-than=<bytes> -Wno-larger-than<bytes> -Wstack-usage=<bytes> (gcc 112, not in 11)
            -Wnoexcept -Wnoexcept-type
            -Wnon-template-friend -Wnon-virtual-dtor
            -Wnonnull -Wnonnull-compare
            -Wnormalized  #=nfc -Wnormalized=[none|id|nfc|nfkc]
            -Wnull-dereference
            -Wodr -Wold-style-cast
            # -Wold-style-declaration -Wold-style-definition (gcc 12, not in 11)
            # -Wopenacc-parallelism (gcc 12, not in 11)
            -Wopenmp-simd -Woverflow
            -Woverlength-strings -Woverloaded-virtual
            # -Woverride-init -Woverride-init-side-effects (gcc 12, not in 11)
            -Wpacked -Wpacked-bitfield-compat -Wpacked-not-aligned
            # -Wpadded (disallows structs that need padding for alignment)
            -Wparentheses
            # -Wpedantic (see above)
            # -Wpessimizing-move (gcc 11, not in gcc 8)
            -Wplacement-new  #=1  -Wplacement-new=<0,2>
            -Wpmf-conversions
            -Wpointer-arith -Wpointer-compare
            # -Wpointer-sign -Wpointer-to-int-cast (gcc 12, not in 11)
            -Wpragmas
            # -Wprio-ctor-dtor (gcc 11, not in gcc 8)
            -Wpsabi
            # -Wrange-loop-construct (gcc 11, not in gcc 10)
            -Wredundant-decls
            # -Wredundant-move (gcc 11, not in gcc 8)
            # -Wredundant-tags (gcc 11, not in gcc 9)
            -Wregister
            # -Wreorder (gcc 12, not in 11)
            -Wreturn-local-addr -Wreturn-type
            -Wrestrict -Wreorder
            -Wscalar-storage-order -Wsequence-point
            -Wshadow -Wshadow-compatible-local -Wshadow-local -Wshadow=compatible-local -Wshadow=local
            -Wshift-count-negative -Wshift-count-overflow -Wshift-negative-value -Wshift-overflow  #=1 -Wshift-overflow=<0,2>
            -Wsign-compare -Wsign-conversion -Wsign-promo
            -Wsized-deallocation
            -Wsizeof-array-argument
            # -Wsizeof-array-div (gcc 11, not in gcc 10)
            -Wsizeof-pointer-div
            -Wsizeof-pointer-memaccess
            -Wstack-protector  # -Wstack-usage=<byte-size>
            -Wstrict-aliasing  #=3  -Wstrict-aliasing=<0,3>
            -Wstrict-null-sentinel  #=1  -Wstrict-overflow=<0,5>
            -Wstrict-overflow  #=1  -Wstrict-overflow=<0,5>
            # -Wstrict-prototypes (gcc 12, not in gcc 11)
            # -Wstring-compare (gcc 11, not in gcc 9)
            -Wstringop-overflow  #=2  -Wstringop-overflow=<0,4>
            # -Wstringop-overread (gcc 11, not in gcc 10)
            -Wstringop-truncation
            -Wsubobject-linkage
            # -Wsuggest-attribute=cold (gcc 12, not in 11)
            -Wsuggest-attribute=const -Wsuggest-attribute=format -Wsuggest-attribute=malloc -Wsuggest-attribute=noreturn
            # -Wsuggest-attribute=pure
            -Wsuggest-final-methods -Wsuggest-final-types
            # -Wsuggest-override (gcc 12, not in gcc 11)
            -Wswitch -Wswitch-bool -Wswitch-default -Wswitch-enum
            # -Wswitch-outside-range (gcc 11, not in gcc 9)
            -Wswitch-unreachable
            -Wsync-nand -Wsynth
            # -Wsystem-headers (expects system headers to be warning-compliant which they are not)
            -Wtautological-compare
            # -Wtemplates (disallows templates, C-tool)
            # -Wterminate -Wtraditional -Wtraditional-conversion (gcc 12, not in 11)
            -Wtrampolines -Wtrigraphs
            # -Wtrivial-auto-var-init (gcc 12, not in 11)
            # -Wtsan (gcc 11, not in 10)
            -Wtype-limits -Wundef -Wuninitialized
            -Wno-unknown-pragmas  # (see above) -Wunknown-pragmas (other compilers need their own pragmas for their warnings)
            -Wunreachable-code -Wunsafe-loop-optimizations
            # -Wunsuffixed-float-constants (gcc 12, not in 11)
            -Wunused -Wunused-but-set-parameter -Wunused-but-set-variable
            # -Wunused-const-variable  #=2 TODO(correaa) add [[maybe_unused]] to niebloids
            -Wunused-function -Wunused-label -Wunused-local-typedefs -Wunused-macros -Wunused-parameter -Wunused-result -Wunused-value -Wunused-variable
            # -Wuse-after-free  # =<0,3> (gcc 12, not in 11)
            -Wuseless-cast
            -Wvarargs -Wvariadic-macros -Wvector-operation-performance
            # -Wvexing-parse (gcc 11, not in gcc 10)
            -Wvirtual-inheritance -Wvirtual-move-assign
            -Wvla
            # -Wvla-larger-than=<number>  (gcc 12, not in 11)
            # -Wvla-parameter (gcc 11, not in gcc 10)
            # -Wvolatile (gcc 11, not in gcc 9)
            -Wvolatile-register-var
            -Wwrite-strings
            -Wzero-as-null-pointer-constant
            # -Wzero-length-bounds (gcc 12, not in 11)
        >
)

我仍然不知道这个列表是否全面。

它可能是,但唯一100%全面的列表是编译器的实际源代码。然而,GCC很大!我不知道所有命令行参数是收集在一个地方还是分散在几个源文件中。还要注意,一些警告是针对预处理器的,一些是针对实际编译器的,还有一些是针对链接器的(链接器是一个完全独立的程序,可以在binutils包中找到),因此它们很可能是分散的。

从本页开始:

注意,一些警告标志不是由-Wall暗示的。其中一些 警告用户通常不考虑的结构 有问题,但偶尔你可能想检查一下; 其他人则对一些必要的或难以避免的短语提出警告 有些情况下,并没有简单的方法来修改代码来抑制 的警告。其中一些是通过-Wextra实现的,但大多数是 必须单独启用。

我想问题是哪些?也许您可以为该页面中所有以-W开头的行进行grep,并获得警告标志的完整列表。然后将它们与-Wall和-Wextra下面的列表进行比较。还有-Wpedantic,尽管你显然想要更迂腐=)

在所有警告都启用的情况下编程是不可能的(除非您打算忽略它们,但那又何必呢?)例如,让我们假设您使用以下标志集:- wstrict - prototyping -Wtraditional。

即使启用了两个警告,下面的程序也会报错。

/tmp $ cat main.c 
int main(int argc, char **argv) {
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c: In function ‘main’:
main.c:1:5: warning: traditional C rejects ISO C style function definitions [-Wtraditional]
 int main(int argc, char **argv) {
     ^

你可能会想“好吧,那我就用旧样式的原型吧”。不,这行不通。

/tmp $ cat main.c 
int main(argc, argv)
    int argc;
    char **argv;
{
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 int main(argc, argv)
     ^

不,不指定任何原型也是错误的,因为编译器也会报错。

/tmp $ cat main.c 
int main() {
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 int main() {
     ^

如果你在程序中定义任何函数,你不能使用所有的标志,因为编译器会抱怨任何可以想象到的函数定义。

对于c++,这是可能的(-Wtraditional标志不存在),并且可以编译非常简单的程序。要启用所有警告,请使用以下警告列表(可能有些警告是重复的,因为我没有费心过滤-Wall启用的警告)。

-Wabi -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Weffc++ -Wstrict-null-sentinel -Wno-non-template-friend -Wold-style-cast -Woverloaded-virtual -Wno-pmf-conversions -Wsign-promo -Wextra -Wall -Waddress -Waggregate-return -Warray-bounds -Wno-attributes -Wno-builtin-macro-redefined -Wc++0x-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wclobbered -Wcomment -Wconversion -Wcoverage-mismatch -Wno-deprecated -Wno-deprecated-declarations -Wdisabled-optimization -Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wignored-qualifiers -Winit-self -Winline -Wno-int-to-pointer-cast -Wno-invalid-offsetof -Winvalid-pch -Wunsafe-loop-optimizations -Wlogical-op -Wlong-long -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wno-mudflap -Wno-multichar -Wnonnull -Wno-overflow -Woverlength-strings -Wpacked -Wpacked-bitfield-compat -Wpadded -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wsign-conversion -Wstack-protector -Wstrict-aliasing=1 -Wstrict-overflow=5 -Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand -Wsystem-headers -Wtrigraphs -Wtype-limits -Wundef -Wuninitialized -Wunknown-pragmas -Wno-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvla -Wvolatile-register-var -Wwrite-strings