168

設定-Wallと設定-std=XXX以外に、Cで使用するために、他に本当に役立つがあまり知られていないコンパイラフラグはありますか?

私は特に、追加の警告、および/または偶発的なタイプの不一致を完全に最小限に抑えるために警告をエラーに変えることに興味があります。

4

24 に答える 24

149

これが私のものです:

  • -Wextra-Wall:必須。
  • -Wfloat-equal:通常、浮動小数点数が等しいかどうかをテストするのは悪いので便利です。
  • -Wundef:初期化されていない識別子が#ifディレクティブで評価された場合に警告します。
  • -Wshadow:ローカル変数が別のローカル変数、パラメーター、またはグローバル変数をシャドウするとき、または組み込み関数がシャドウされるときはいつでも警告します。
  • -Wpointer-arith:関数またはのサイズに依存するものがある場合は警告しますvoid
  • -Wcast-align:ターゲットの必要な配置が増加するようにポインタがキャストされるたびに警告します。たとえば、整数が2バイトまたは4バイトの境界でのみアクセスできるマシンでachar *がキャストされた場合は警告します。int *
  • -Wstrict-prototypes:引数の型を指定せずに関数が宣言または定義された場合に警告します。
  • -Wstrict-overflow=5:符号付きオーバーフローが発生しないという仮定に基づいてコンパイラが最適化する場合について警告します。(値5は厳しすぎる可能性があります。マニュアルページを参照してください。)
  • -Wwrite-strings:文字列定数に型のconst char[長さを指定して、1つのアドレスを非ポインタ]にコピーすると警告が表示されるようにします。const char *
  • -Waggregate-return:構造体または共用体を返す関数が定義または呼び出された場合に警告します。
  • -Wcast-qual:ターゲット型から型修飾子を削除するためにポインタがキャストされるたびに警告します*
  • -Wswitch-defaultswitch:ステートメントに大文字と小文字が含まれていないdefault場合は常に警告します*
  • -Wswitch-enumswitch:ステートメントに列挙型のインデックスがあり、caseその列挙の1つ以上の名前付きコードのaがない場合は常に警告します*
  • -Wconversion:値を変更する可能性のある暗黙の変換について警告します*
  • -Wunreachable-code:コードが実行されないことをコンパイラが検出した場合に警告します*

*のマークが付いているものは、誤った警告が多すぎることがあるので、必要に応じて使用します。

于 2010-07-31T02:10:52.043 に答える
69

-fコード生成オプションのいくつかは興味深いものです。

  • -fverbose-asmアセンブリ出力を調べるためにコンパイルする場合に便利です-S-いくつかの有益なコメントを追加します。

  • -finstrument-functionsすべての関数の入口と出口でユーザー提供のプロファイリング関数を呼び出すコードを追加します。

  • --coveragegcovプログラム内のブランチと呼び出しを計測し、カバレッジノートファイルを作成します。これにより、プログラムの実行時に、テストカバレッジの分析に役立つようにプログラムでフォーマットできるカバレッジデータが生成されます。

  • -fsanitize={address,thread,undefined}AddressSanitizer、ThreadSanitizer、およびUndefinedBehaviorSanitizerコードサニタイザーをそれぞれ有効にします。これらは、実行時にさまざまな種類のエラーをチェックするためにプログラムを計測します。

以前、この回答にも言及されていましたが、この機能は、によって有効にされた消毒剤の1つに-ftrapv取って代わられました。-fsanitize=signed-integer-overflow-fsanitize=undefined

于 2010-07-31T01:35:14.280 に答える
56

常に-O以上(-O1、、、-O2など-Os)を使用してください。デフォルトの最適化レベルでは、gccはコンパイル速度を重視し、単一化された変数などについて警告するのに十分な分析を行いません。

-Werrorコンパイルを停止しない警告は無視される傾向があるため、ポリシーの作成を検討してください。

-Wallエラーである可能性が非常に高い警告をほぼオンにします。

に含まれる警告は、-Wextra一般的な正当なコードにフラグを立てる傾向があります。それらはコードレビューに役立つかもしれませんが(lintスタイルのプログラムはより多くの落とし穴がより柔軟であることがわかりますが)、通常の開発ではそれらをオンにしません。

-Wfloat-equalプロジェクトの開発者が浮動小数点に慣れていない場合は良い考えであり、慣れていない場合は悪い考えです。

-Winit-self便利です。なぜ含まれていないのかしら-Wuninitialized

-Wpointer-arithで動作しないほとんど移植可能なコードがある場合に便利です-pedantic

于 2010-07-30T22:29:27.863 に答える
41
-save-temps

これにより、プリプロセッサとアセンブリの結果が残ります。

前処理されたソースは、マクロのデバッグに役立ちます。

このアセンブリは、どの最適化が有効になったかを判断するのに役立ちます。たとえば、GCCが一部の再帰関数で末尾呼び出しの最適化を行っていることを確認したい場合があります。これがないと、スタックがオーバーフローする可能性があります。

于 2010-08-03T18:58:32.407 に答える
40

まだ誰もこれを言っていないことに驚いています-私に関する限り、最も有用なフラグは、-gデバッグ情報を実行可能ファイルに入れて、デバッグしてソースをステップスルーできるようにすることです(アセンブリを熟知して読んでいる場合を除きます)。stepiプログラムの実行中のコマンドのように)。

于 2010-07-30T22:23:27.970 に答える
36

-fmudflap -UBをキャッチするために、すべての危険なポインター操作にランタイムチェックを追加します。これにより、プログラムが再びバッファオーバーフローを効果的に免除され、あらゆる種類のダングリングポインタをキャッチするのに役立ちます。

これがデモです:

$ cat mf.c 
int main()
{
 int a[10];
 a[10]=1; // <-- o noes, line 4
}

$ gcc -fmudflap mf.c -lmudflap
$ ./a.out 
*******
mudflap violation 1 (check/write): time=1280862302.170759 ptr=0x7fff96eb3d00 size=44
pc=0x7f3a575503c1 location=`mf.c:4:2 (main)'
      /usr/lib/libmudflap.so.0(__mf_check+0x41) [0x7f3a575503c1]
      ./a.out(main+0x90) [0x400a54]
      /lib/libc.so.6(__libc_start_main+0xfd) [0x7f3a571e2c4d]
Nearby object 1: checked region begins 0B into and ends 4B after
mudflap object 0xf9c560: name=`mf.c:3:6 (main) a'
bounds=[0x7fff96eb3d00,0x7fff96eb3d27] size=40 area=stack check=0r/3w liveness=3
alloc time=1280862302.170749 pc=0x7f3a57550cb1
number of nearby objects: 1
于 2010-08-03T18:50:33.377 に答える
25

C / C ++とはあまり関係ありませんが、とにかく便利です:

@file

上記のすべての適切なフラグ(すべて指定したもの)を「ファイル」に入れ、この上記のフラグを使用して、そのファイル内のすべてのフラグを一緒に使用します。

例えば:

ファイル:compilerFlags

-壁

-std = c99

-Wextra

次にコンパイルします:

gcc yourSourceFile @compilerFlags
于 2013-07-15T06:47:00.537 に答える
17

-march=nativeコンパイルするプラットフォーム(=チップ)用に最適化されたコードを生成する

于 2010-07-31T07:33:17.000 に答える
16

コンパイラーによって事前定義されているプリプロセッサー・フラグを知る必要がある場合:

echo | gcc -E -dM -
于 2010-07-31T13:46:59.863 に答える
15

エラーの検出にはあまり役立ちませんが、めったに言及されない-masm=intelオプションを使用-Sすると、アセンブリ出力の検査がはるかに便利になります。

AT&Tアセンブリ構文は、頭を痛めすぎます。

于 2010-08-04T06:15:31.440 に答える
11

これは言及されていない素晴らしい旗です:

-Werror-implicit-function-declaration

関数が宣言される前に使用されるときはいつでもエラーを出します。

于 2010-08-14T15:59:57.047 に答える
10

私のmakefileには通常

  CFLAGS= -Wall -Wextra -Weffc++ -Os -ggdb
  ...
  g++ $(CFLAGS) -o junk $<
  gcc $(CFLAGS) -o $@ $<
  rm -f junk

これらのオプションの中で最も重要なものは以前に説明されているので、まだ指摘されていない2つの機能を指摘します。

適切なC++コンパイラがまだないプラットフォームへの移植性のためにプレーンCである必要があるコードベースに取り組んでいますが、C ++コンパイラ(Cコンパイラに加えて)を使用して「追加」コンパイルを行います。これには3つの利点があります。

  1. C ++コンパイラは、Cコンパイラよりも優れた警告メッセージを表示することがあります。
  2. C++コンパイラは-Weffc++オプションを受け入れます。これにより、いくつかの役立つヒントが得られることがあります。これは、プレーンCでのみコンパイルした場合には見逃してしまいます。
  3. プレーンなCコードが無効なC++コードであるいくつかの境界条件(「bool」という名前の変数の定義など)を回避して、コードをC++に移植するのを比較的簡単に保つことができます。

はい、私は絶望的に楽観的なPollyannaであり、1つのプラットフォームが廃止されたと宣言されるか、まともなC ++コンパイラを取得し、最終的にC++に切り替えることができるようになると確信しています。私の考えでは、それは避けられないことです。唯一の問題は、経営陣が最終的に全員にポニーを発行する前か後かということです。:-)

于 2010-08-13T21:33:51.073 に答える
9
-Wstrict-prototypes -Wmissing-prototypes
于 2010-07-30T22:32:46.927 に答える
8
man gcc

マニュアルには、わかりやすい説明が付いた興味深いフラグがたくさんあります。ただし、-Wallはおそらくgccを可能な限り冗長にします。より興味深いデータが必要な場合は、valgrindまたはその他のエラーチェックツールを確認する必要があります。

于 2010-07-30T22:09:07.273 に答える
7

-Werrorすべての警告をエラーとして扱い、コンパイルを停止するがあります。gccマニュアルページでは、コンパイラのすべてのコマンドラインスイッチについて説明しています。

于 2010-07-30T22:09:18.147 に答える
6

まあ、-Wextra標準でもあるはずです。-Werror警告をエラーに変えます(これは、特になしでコンパイルする場合、非常に-Wno-unused-result煩わしい場合があります)。-pedanticと組み合わせると、std=c89C99機能を使用する場合に追加の警告が表示されます。

しかし、それはそれについてです。CコンパイラをC自体よりも型を節約するものに調整することはできません。

于 2010-07-30T22:14:04.287 に答える
6

-M*オプションのファミリー。

これらを使用すると、cまたはc++ソースファイルが依存するヘッダーファイルを自動的に把握するmakeファイルを作成できます。GCCは、この依存関係情報を使用してmakeファイルを生成し、プライマリmakeファイルからそれらをインクルードします。

これは、-MDと-MPを使用した非常に一般的なmakefileの例で、c ++ソースファイルとヘッダーファイルでいっぱいのディレクトリをコンパイルし、すべての依存関係を自動的に把握します。

CPPFLAGS += -MD -MP                                         
SRC = $(wildcard *.cpp)                                                       

my_executable: $(SRC:%.cpp=%.o)                                                        
        g++ $(LDFLAGS) -o $@ $^                                               

-include $(SRC:%.cpp=%.d)

これについて詳しく説明しているブログ投稿は次のとおりです。http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html

于 2012-01-06T21:47:37.700 に答える
5

このスレッドが特定の問題を修正するためのフラグを探しているのを見つけました。ここには表示されないので、私の投稿で困惑していたフラグを追加します。

-Wformat=2旗_

-Wformatprintf=>やなどの呼び出しをチェックscanfして、指定されたフォーマット文字列に適切な型が指定された引数を持っていることを確認します。

そしてそれについての本当に重要な部分(GCCマニュアルによると):

-Wformatに含まれてい-Wallます。フォーマットチェックのいくつかの側面をより細かく制御するために、オプション-Wformat-y2k、、、、、、-Wno-format-extra-argsおよびが使用可能ですが-Wno-format-zero-length、-Wallには含まれていません-Wformat-nonliteral-Wformat-security-Wformat=2

だから、あなたが持っているからといって、-Wallあなたがそれをすべて持っているという意味ではありません。;)

于 2012-10-25T12:56:54.833 に答える
4

私は時々-s、はるかに小さい実行可能ファイルに使用します。

-s
    Remove all symbol table and relocation information from the executable.

ソース: http: //gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options

于 2010-07-31T00:38:41.947 に答える
4

-Wfloat-equal

差出人:http ://mces.blogspot.com/2005/07/char-const-argv.html

私が好きな他の新しい警告の1つは、-Wfloat-equalです。これは、等式条件で浮動小数点数を[持っている]ときはいつでも警告します。それは素晴らしいです!コンピュータグラフィックスまたは(さらに悪い:)計算幾何学アルゴリズムをすべてプログラムした場合、2つのフロートが同等に一致することはないことを知っています...

于 2010-07-31T13:06:29.867 に答える
3

この答えは少し話題から外れているかもしれませんが、質問は私からの価値のある+1です。

私は特に、追加の警告、および/または偶発的なタイプの不一致を完全に最小限に抑えるために警告をエラーに変えることに興味があります。
明らかではないかもしれないすべてのエラーと潜在的なエラーをキャッチする必要があるツールがあります。IMHOがgccや他のコンパイラと比較してエラーをキャッチするのにはるかに優れた仕事をするスプリントがあります。それはあなたの道具箱に持っている価値のある道具です。

スプリントなどのlintタイプのツールを介した静的チェックは、コンパイラツールチェーンの一部である必要があります。

于 2010-08-09T15:04:13.033 に答える
2

私は特に追加の警告に興味があります、

に加えて-Wall-Wor-Wextraオプション(-W古いバージョンのgccと新しいバージョンで機能します。新しいバージョンは代替名-Wextraをサポートします。これは同じことを意味しますが、より説明的です)、さまざまな追加の警告を有効にします。

また、一般的にもっと疑わしいほど悪いものに対して、これらのどちらによっても有効にされない警告がさらにあります。使用可能なオプションのセットは、使用しているgccバージョンによって異なります。詳細については、man gccまたはinfo gcc詳細を参照するか、関心のある特定のgccバージョンのオンラインドキュメント-pedanticを参照してください。また、使用されている特定の標準で必要なすべての警告を発行します(-std=xxxまたは)などの他のオプション-ansiについては、gcc拡張機能の使用について不平を言います。

および/または偶発的なタイプの不一致を完全に最小限に抑えるために、場合によっては警告をエラーに変換します。

-Werrorすべての警告をエラーに変えます。ただし、gccでは特定の警告に対して選択的にそれを実行できるとは思いません。

-Werror外部ライブラリからのヘッダーファイルがそれらの一部をトリップする可能性があるため、プロジェクトごとに有効にする警告を選択する必要があることに気付くでしょう(特にを使用する場合)。(-pedantic特に、私の経験では、この点では役に立たない傾向があります。)

于 2010-07-30T22:10:05.873 に答える
1
  • -Wmissing-prototypes:グローバル関数が事前のプロトタイプ宣言なしで定義されている場合。
  • -Wformat-security:セキュリティ上の問題の可能性を表すフォーマット関数の使用について警告します。現在、これは、フォーマット文字列が文字列リテラルではなく、フォーマット引数がない関数の呼び出しprintfと関数について警告しますscanf
于 2018-02-07T09:35:07.177 に答える
1
  • -Werror=return-type:関数がgccに戻り値を持たない場合にエラーを強制します。VisualStudioにあり/we4716ます。

  • -Werror=implicit-function-declaration:関数が定義されていない/含まれていない場合にエラーを強制します。VisualStudioにあり/we4013ます。

  • -Werror=incompatible-pointer-types:ポインタの型が予想されるポインタの型と一致しない場合は、エラーが発生します。VisualStudioにあり/we4133ます。

実際、Cコードをクロスプラットフォームに保ちたいので、CMakeを使用し、提供されたcflagsを次のようにCMakeLists.txtに配置します。

if (CMAKE_SYSTEM_NAME MATCHES "Windows")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /we4013 /we4133 /we4716")
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration -Werror=incompatible-pointer-types -Werror=return-type")
endif()
于 2018-11-27T11:05:32.767 に答える