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


194

文字通り、GCCが提供するすべての警告を有効にしたいと思います。(それは簡単だと思います...)

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

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

GCCにすべての警告を有効にするように指示するにはどうすればよいですか(if、and、およびnoです!)。


27
@Arafangion:質問について何が「不明確」なのか理解できません-はい、私はコードに適用されるすべての警告を有効にしたいと思います。その理由は非常に簡単です。-Wallまたは-Wextraによってオンにならない警告の一部が役立つことがわかったので、残りを試して、コードを改善できるかどうかを確認したいと思います。それはそれと同じくらい簡単です。
user541686 2012

12
@JoachimPileborg:「コンパイラに警告する内容は何ですか?」潜在的なエラーおよび/または悪いスタイル?つまり、正確な警告をすべて知っていれば、手動でオンにするだけで、質問をする必要はありません。答えが実際に「すべてを見つけるにはソースコードを見る必要がある」場合は、答えとして投稿してください。
user541686 2012

56
clang 3.1はを提供しています-Weverything
Alexandre Hamez

5
@Arafangionさて、質問にはC ++のタグが付けられているので... :)
一部のプログラマー

5
@JoachimPileborgそして、ソースから警告を抽出する自動化された方法が(ついに)そこにあります:github.com/barro/compiler-warnings
Kyle Strand

回答:


129

できません。

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

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

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

-Weffc++はノイズが多すぎて役に立たないと思います。これは、Effective C ++の古い第1版に基づいており、完全に有効なC ++である構文について警告します(このガイドラインは、本の後の版で変更されました)。std::stringコンストラクターでメンバーを初期化していないことを警告しました。私が望んでいることを正確に実行するデフォルトのコンストラクタがありますが、それm_str()を呼び出すように書く必要があるのはなぜですか?-Weffc++参考になる警告は、コンパイラが(偽陰性を与える)を正確に検出するために非常に困難であり、そのような明示的にすべてのメンバーを初期化として有用でないものは、ちょうど偽陽性を与え、あまりにも多くのノイズを生成します。

Luc Dantonは、C ++コードではほとんど間違いなく意味のない、役に立たない警告の優れた例を提供しました-Waggregate-return

つまり、本当にすべての警告が必要なわけではなく、必要なだけだと思います。

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

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

重要な警告もあれば、重要でない警告もあります。あなたは差別的でなければならず、そうでなければあなたのプログラムを台無しにしてしまいます。たとえば、を考えます-Wdouble-promotion。組み込みシステムで作業している場合、これが必要になることがあります。デスクトップシステムで作業している場合は、おそらく使用しません。そして、あなたは欲しい-Wtraditionalですか?疑わしい。

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

編集2:コンパイラのバージョンに応じて異なる警告を使用する必要があるメイクファイルに関するDevSolarの不満に応えて、-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))

38
「マニュアルを読み、それらについて読み、どれを有効にするかを決定し、それらを試してください。」ここでの問題は、省略した手順です。「コンパイラバージョンごとにマニュアルを再確認し、警告のリストを変更してください。変更します。Makefileで正確なコンパイラバージョンを確認し、の警告リストを使用してください。それぞれに。」メンテナーが維持する最適化レベルがあります。警告に対して同じサービスを提供することに煩わされなかったのはなぜですか?
DevSolar 2012

17
@JonathanWakely:私のプロジェクトはありますが、GCCはその中にありません。彼らの製品の弱点を指摘します。彼らがそれを修正するか、そうしないことのせいで彼らは責任を受け入れるかのどちらかですが、彼らのためにそれを修正するのは私次第ではありません。
DevSolar 2012

14
@JonathanWakely:「何かが必要な場合は、それについて聞いてみてください。-私はそれを批判するためにGCCプロジェクトに参加する義務はありません。特に、#31573がすでにWONTFIXとしてフラグされている場合はそうです。それはこの主題を「それについて尋ねる」から「それについて雌犬」の球場に入れます。
DevSolar 2012

61
-Weverything私は、そのようなオプションを与えないというgcc戦略よりも優れた解決策だと思います。私の哲学はデフォルトですべての警告をオンにすることです(誰かがコンパイラーに追加するのに十分役立つと思ったため)ので、このフラグをclangで使用します。それが気に入らない場合は、特にその警告をオフにします。重要なのは、トリガーしない警告については知らないが、トリガーしたくない警告については知っていて、簡単にオフにできることです。
David Stone

17
@JonathanWakelyええ、でも彼らは淡々としている。コードに関連する可能性のある警告を確認する最も簡単な方法は、コードによってトリガーされる警告を確認することです。その時点で、警告を無効にするかどうかを決定する前に、潜在的に危険なコードの関連する実際の例を確認できます。これはClangの-Weverythingオプションで簡単に実行できますが、GCCでは実行できません。
カイルストランド

71

文字通りすべての警告を有効にすることはおそらく有益ではないという以前の回答に同意しますが、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 -after-statement -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 -Wintrinsics-shadow -Wintrinsics-std -Winvalid-memory-model -Winvalid-offsetof -Winvalid-pch -Wjump-misses-init -Wline-truncation -Wliteral-suffix -Wlogical -not-parentheses -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-style-declaration -Wold-style-definition -Wopenmp-simd -Woverflow -Woverlength-strings -Woverloaded-virtual -Woverride-init -Wpacked -Wpacked-bitfield-compat -Wpadded -Wparentheses -Wpedantic -Wpmf-conversions -Wpointer-arith -Wpointer-sign -Wpointer-to-int-cast -Wpragmas -Wproperty -assign-default -Wprotocol -Wreal-q-constant -Wrealloc-lhs -Wrealloc-lhs-all -Wredundant-decls -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-headers -Wtabs -Wtarget-lifetime -Wtraditional -Wtraditional-conversion -Wtrampolines -Wtrigraphs -Wtype-limits -Wundeclared-selector -Wundef -Wunderflow -Wuninitialized -Wunknown-pragmas -Wunsafe-loop-optimizations -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、呼び出しの最後に適切なものを追加することで回避できます。


10
それは実用的ではないと思います。Gccはstd libからの警告を表示しています。
Valentin Heinitz、2016

13
@ValentinHeinitz言ったように、文字通りすべての警告を有効にすることは有益ではないと思いますが、これはOPが求めていたものです。ただし、他の回答ですでに言及されているいくつかの問題のある警告を明示的に削除すると(たとえば、呼び出しの最後にそれぞれ-Wno-whateverを追加することにより)、これは実用的である可能性があります。
Haatschii 2017

6
@ValentinHeinitz 関連するディレクトリの-isystem代わりに-Iを使用して、gccがsystem / std / 3rd-partyヘッダーの警告を発行しないようにすることができます。
カイルストランド

4
これは実際にそして直接質問に答えるので、これは受け入れられた答えであるべきです。
TFuto

16

すべての警告を有効にしてプログラミングすることは単純に不可能です(それらを無視するつもりがない場合は、なぜ気になるのでしょうか?)。たとえば、次のフラグのセットを使用するとします-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 isnt 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 isnt 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

13
私はこれまでこれをチェックする気になりませんでしたが、実際には不可能ではありません...試してくださいint main(int, char **); int main(argc, argv) int argc; char **argv; { (void)argc; (void)argv; return 0; }
user541686

2
この簡単なプログラムを使用しても、「警告:スタック使用量は16バイトです(-Wstack-usage =]」;-)
Marc Glisse

7

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

GCCでは(Clangとは異なり)GCCがを提供していないため、すべての警告を確実にオンにする唯一の方法は、GCCの場合、このツールによって提供されるコンパイラバージョンの警告の完全なリストからコピーすることです。-Weverything

ツールc.optはGCCソースコードの実際のファイルを解析するように見えるので、その結果決定的なものになります。

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

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


これが答えです。「トップレベル」リストを使用して、トップレベル(インデント/ネストされていない)にあるすべての引数を追加します。github.com/Barro/compiler-warnings/blob/master/gcc/...
ジェットスキーS型

6

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 }'


3

このページから:

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

私の質問は どちらのものですか?おそらく、-Wで始まるすべての行についてそのページをgrepし、警告フラグの完全なリストを取得できます。そして、下のリストと、それらを比較-Wallして-Wextra。さらにあり-Wpedanticますが、あなたは明らかにさらにまだ知識を深めたいと思っています=)


「そして、このリストが包括的であるかどうかはまだわかりません」 ...はい、確かにそのページをgrepできますが、問題はそれが包括的かどうかです。
user541686 2012

1
わかりません... GCCのソースコードを注ぐ必要があるかもしれません。プログラマーとしての生活を非常に困難にしようとしているのですか、それとも考えられるすべての警告を表示したいのには理由がありますか?=)
水田

2
GCCによるコードの診断を確認したいのですが、これは非常に役立ちます。しかし、明らかに、すべての警告とどの警告が有用であるか(そしてどの警告が有用でないか)をすでに知っていれば、質問することは何もありませんでした。実際に試してみないとわからないのですが(たとえば、シャドウイングが役に立ったので、オフになっているだけでは役に立たないわけではありません)。
user541686 2012

3

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

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


3
すべてのオプションを1つのページにグループ化する私の回答の[オプションの概要]ページにリンクしました。GCCコードレビューポリシーでは、ドキュメントなしで新しいオプションを許可しないため、ドキュメントは包括的である必要があります。
Jonathan Wakely、2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.