web-dev-qa-db-ja.com

GCCのすべての警告を(文字通り)有効にする方法は?

GCCが持っている警告の-文字通り-ALLを有効にしたいと思います。 (簡単だと思うでしょう...)

  • あなたは-Wallがトリックをするかもしれないと思うだろうが、いや! -Wextraがまだ必要です。

  • あなたは-Wextraがトリックをするかもしれないと思うだろうが、いや!リストされているすべての警告 here (たとえば、-Wshadow)がこれによって有効になっているわけではありません。そして、このリストが包括的かどうかはまだわかりません。

GCCに(if、and、またはbut!ではない!)all警告を有効にするように指示するにはどうすればよいですか?

172
Mehrdad

できません。

GCC 4.4.0のマニュアルは、そのバージョンについてのみ包括的なものですが、4.4.0で発生する可能性があるすべての警告をリストしています。ただし、リンク先のページにすべてが存在するわけではありません。たとえば、一部の言語固有のオプションは、C++オプションまたはObj-Cオプションのページにあります。それらをすべて見つけるには、 オプションの概要

everythingをオンにすると、-Wdouble-promotionが含まれます。これは、floatを実装する32ビットの単精度浮動小数点ユニットを持つCPUにのみ関連します。ハードウェアですが、ソフトウェアでdoubleをエミュレートします。 doubleとして計算を行うと、ソフトウェアエミュレーションが使用され、速度が低下します。これは一部の組み込みCPUに関連していますが、64ビット浮動小数点のハードウェアサポートを備えた最新のデスクトップCPUには完全に無関係です。

通常は役に立たない別の警告は-Wtraditionalです。これは、従来のCで異なる意味を持つ(または機能しない)完全に整形されたコードについて警告します。 "string " "concatenation"、またはISO C関数定義! 30年前のコンパイラとの互換性に本当に関心がありますか? int inc(int i) { return i+1; }の書き込みに関する警告が本当に必要ですか?

-Weffc++はうるさすぎて役に立たないと思います。これはEffective C++の古い初版に基づいており、完全に有効なC++(および後の版でガイドラインが変更されたもの)について警告します私のコンストラクタでstd::stringメンバーを初期化していないことを警告したくありません。それは私が望むことを正確に行うデフォルトのコンストラクタを持っていますが、それを呼び出すためにm_str()を書く必要があるのはなぜですか?役立つと思われる-Weffc++警告は、コンパイラーが正確に検出するのが難しすぎて(偽陰性を与える)、すべてのメンバーを明示的に初期化するなどの役に立たないものは、過度のノイズを生成し、偽を与えますポジティブ。

Luc Dantonは-Waggregate-returnからの無用な警告の 素晴らしい例 を提供しましたが、これはほとんど確実にC++コードには意味がありません。

つまり、実際にはall警告は必要ありません。

マニュアルを読み、それらについて読んで、どれを有効にしたいかを決めて、試してください。コンパイラのマニュアルを読むことは良いことですTM とにかく、特にRTFMを避けたい場合は、ショートカットを作成して理解できない警告を有効にすることはあまり良い考えではありません。

オンにするだけの人すべては、おそらく無知であるか、または先のとがった髪のボスが「警告なし」と言ったためにそうしています

一部の警告は重要で、一部は重要ではありません。差別する必要があるか、プログラムを台無しにする必要があります。たとえば、-Wdouble-promotionを検討してください。組み込みシステムで作業している場合は、これ;あなたがデスクトップシステムで作業しているなら、おそらくそうしないでしょう。そして、あなたは-Wtraditionalが欲しいですか?私はそれを疑います。

Edit:すべての警告を有効にする -Wall-all も参照してください。これはWONTFIXとして閉じられます。

編集2:-Wall -Wextraが適切でない場合、コンパイラのバージョンに応じて異なる警告を使用する必要があるメイクファイルに関するDevSolarの苦情に対応してコンパイラ固有およびバージョン固有の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))
116
Jonathan Wakely

私は、文字通りすべての警告を有効にすることはおそらく有益ではないという以前の回答に同意しますが、GCCはこれを達成するための合理的に便利な方法を提供します。コマンド

gcc -Q --help=warning

サポートされているすべての警告オプションのリストと、それらがアクティブかどうかに関する情報を提供します。ちなみにこれは、たとえば-Wallおよび-Wextra

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

すべての警告を有効にするには、正規表現を使用してコマンドラインパラメーターを抽出します。

gcc -Q --help=warning | sed -e 's/^\s*\(\-\S*\)\s*\[\w*\]/\1 /gp;d' | tr -d '\n'

私の現在のGCCの場合、これにより以下が得られます。

-Wabi -Wabi-tag -Waddress -Waggregate-return -Waggressive-loop-optimizations -Waliasing -Walign-commons -Wampersand -Warray-bounds -Warray-temporaries -Wassign-intercept -Wattributes -Wbad-function-cast -Wbool-compare -Wbuiltin-macro-redefined -Wc ++-compat -Wc ++ 0x-compat -Wc ++ 14-compat -Wc-binding-type -Wc90-c99-compat -Wc99-c11-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wcharacter-truncation -Wchkp -Wclobbered -Wcomment -Wcompare-reals -Wconditionally-supported -Wconversion -Wconversion-extra -Wconversion-null -Wcoverage-mismatch -Wcpp -Wctor-dtor-privacy -Wdate-time -Wdeclaration -文の後-Wdelete-incomplete -Wdelete-non-virtual-dtor -Wdeprecated -Wdeprecated-declarations -Wdesignated-init -Wdisabled-optimization -Wdiscarded-array-qualifiers -Wdiscarded-qualifiers -Wdiv-by-zero -Wdouble-promotion -Weffc ++ -Wempty-body -Wendif-labels -Wenum-compare -Wextra -Wfloat-equal -Wformat-contains-nul -Wformat-extra-args -Wformat-nonliteral -Wformat-security -Wformat-signedness- Wformat-y2k -Wformat-zero-length -Wfree-nonheap-object -Wfunction-elimination -Wignored-qualifiers -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wimplicit-interface -Wimplicit-procedure -Wincompatible-pointer-types- Winherited-variadic-ctor -Winit-self -Winline -Wint-conversion -Wint-to-pointer-cast -Wintrinsic-shadow -Wintrinsics-std -Winvalid-memory-model -Winvalid-offsetof -Winvalid-pch -Wjump-misses- init -Wline-truncation -Wliteral-suffix -Wlogical-not-かっこ-Wlogical-op -Wlong-long -Wmain -Wmaybe-uninitialized -Wmemset-transposed-args -Wmissing-braces -Wmissing-declarations -Wmissing-field-initializers- Wmissing-include-dirs -Wmissing-parameter-type -Wmissing-prototypes -Wmultichar -Wnarrowing -Wnested-externs -Wnoexcept -Wnon-template-friend -Wnon-virtual-dtor -Wnonnull -Wodr -Wold-style-cast -Wold-スタイル宣言-Wold-style-definition -Wopenmp-simd -Woverflow -Woverlength-strings -Woverloaded-virtual -Woverride-init -Wpacked -Wpacked-bitfield-compat -Wpadde d -Wparentheses -Wpedantic -Wpmf-conversions -Wpointer-arith -Wpointer-sign -Wpointer-to-int-cast -Wpragmas -Wproperty-assign-default -Wprotocol -Wreal-q-constant -Wrealloc-lhs -Wrealloc-lhs-すべて-冗長冗長-Wreorder -Wreturn-local-addr -Wreturn-type -Wselector -Wsequence-point -Wshadow -Wshadow-ivar -Wshift-count-negative -Wshift-count-overflow -Wsign-compare -Wsign-promo- Wsized-deallocation -Wsizeof-array-argument -Wsizeof-pointer-memaccess -Wstack-protector -Wstrict-null-sentinel -Wstrict-prototypes -Wstrict-selector-match -Wsuggest-attribute = const -Wsuggest-attribute = format -Wsuggest- attribute = noreturn -Wsuggest-attribute = pure -Wsuggest-final-methods -Wsuggest-final-types -Wsuggest-override -Wsurprising -Wswitch -Wswitch-bool -Wswitch-default -Wswitch-enum -Wsync-nand -Wsynth -Wsystem-ヘッダー-Wtabs -Wtarget-lifetime -Wtraditional -Wtraditional-version -Wtrampolines -Wtrigraphs -Wtype-limits -Wundeclared-selector -Wundef -Wunderflow -Wuninitialized -Wunknown-pragmas -Wuns afe-loop-optimizations -Wunsuffixed-float-constants -Wunused -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-dummy-argument -Wunused-function -Wunused-label -Wunused-local-typedefs- Wunused-macros -Wunused-parameter -Wunused-result -Wunused-value -Wunused-variable -Wuse-without-only -Wuseless-cast -Wvarargs -Wvariadic-macros -Wvector-operation-performance -Wvirtual-move-assign -Wvla- Wvolatile-register-var -Wwrite-strings -Wzero-as-null-pointer-constant -Wzerotrip -frequire-return-statement

これを使用して、GCCを呼び出すことができます。

gcc $(gcc -Q --help=warning | sed -e 's/^\s*\(\-\S*\)\s*\[\w*\]/\1 /gp;d' | tr -d '\n')

ただし、一部の警告オプションは特定の言語でのみ使用可能なため、これにより警告が発生します(例:C++)。これらは、現在の言語で許可されているオプションのみを含む正規表現を使用するか、呼び出しの最後に適切な-Wno-whateverを追加することで回避できます。

58
Haatschii

すべての警告を有効にしてプログラムすることは、単に不可能です(それらを無視する場合を除き、それでは、なぜ気にしますか?)。たとえば、次のフラグセットを使用するとします:-Wstrict-prototypes -Wtraditional

2つの警告が有効になっている場合でも、次のプログラムはエラーを出します。

/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
15
Konrad Borowski

誰かが、特定のGCCまたはClangバージョンのcomplete警告セットを決定するためのツールセットを作成しました。

GCCの場合、コンパイラバージョンにこのツールによって提供される警告の完全なリストからコピーすると、all警告が有効になることを保証するonlyのように見えますClang)GCCは-Weverythingを提供しません。

このツールは、GCCソースコード内の実際のc.optファイルを解析するように見えるため、その結果shouldが決定的です。

リポジトリには、ほとんどのGCCおよびClangバージョン(現在はClang 3.2から3.7およびGCC 3.4から5.3)で生成された警告リストを含むテキストファイルも含まれています。

https://github.com/barro/compiler-warnings

5
Kyle Strand

Gcc 4.3+に-Q --help = warningsが追加されました。--help = warnings、Cを指定して、C関連の警告のみを出力することもできます。

これを利用するためにm4モジュールを作成しました(clangの-Weverythingもサポートしています)。 wget_manywarnings.m4 を参照してください。

使い方は非常に簡単です。基本的に、モジュールはすべての警告フラグをオンにします。そして、必要に応じて警告を削除します-一部は非常に冗長です。例: configure.ac

Autotoolsを使用しない場合、m4モジュールで無効になっているすべての警告を有効にするコードがあります。これは、基本的にawkを介してパイプされるgcc呼び出しです。

flags="-Wall -Wextra -Wformat=2 "$(gcc -Wall -Wextra -Wformat=2 -Q --help=warning,C|awk '{ if (($2 == "[disabled]" || $2 == "") && $1!~/=/ && $1~/^-W/&& $1!="-Wall") print $1 }'

5
rockdaboot

そして、このリストが包括的かどうかはまだわかりません。

おそらくそうですが、100%包括的である唯一のリストは、コンパイラの実際のソースです。ただし、GCCはbig!です。また、すべてのコマンドラインパラメーターが1か所で収集されているのか、複数のソースファイルに分散しているのかわかりません。また、一部の警告はプリプロセッサ、一部は実際のコンパイラ、一部はリンカ(完全に独立したプログラムであり、binutilsパッケージにあります)に対応しているため、ほとんどの場合警告が広まっていることに注意してください。

このページ から:

一部の警告フラグは、-Wallによって暗示されないことに注意してください。それらのいくつかは、ユーザーが一般的に疑わしいとは思わない構造について警告しますが、時々チェックすることを望むかもしれません。また、場合によっては回避が必要または困難な構造について警告するものもあり、コードを変更して警告を抑制する簡単な方法はありません。それらの一部は-Wextraによって有効になりますが、それらの多くは個別に有効にする必要があります。

質問はwhich ones?おそらく、-Wで始まるすべての行についてgrepそのページを表示し、警告フラグの完全なリストを取得できます。次に、それらを-Wallおよび-Wextraの下のリストと比較します。 -Wpedanticもありますが、あなたは明らかにもっと慢になりたいと思っていますが=)

3
paddy