設定を越えて-Wall
、設定-std=XXX
、その他の本当に便利な、あまり知られているコンパイラフラグは、Cでの使用のために何がありますか?
偶発的なタイプの不一致を完全に最小限に抑えるために、追加の警告や、場合によっては警告をエラーに変換することに特に興味があります。
gcc -c [flags-go-here] -o myprog.o myprog.c
Cプログラムを(リンクではなく)コンパイルするために実行しています。
設定を越えて-Wall
、設定-std=XXX
、その他の本当に便利な、あまり知られているコンパイラフラグは、Cでの使用のために何がありますか?
偶発的なタイプの不一致を完全に最小限に抑えるために、追加の警告や、場合によっては警告をエラーに変換することに特に興味があります。
gcc -c [flags-go-here] -o myprog.o myprog.c
Cプログラムを(リンクではなく)コンパイルするために実行しています。
回答:
-f
コード生成オプションのいくつかは興味深いものです。
この-ftrapv
関数は、符号付き整数オーバーフローでプログラムを中止させます(以前はCでは「未定義の動作」)。
-fverbose-asm
でコンパイルし-S
てアセンブリの出力を調べる場合に便利です。これにより、有益なコメントが追加されます。
-finstrument-functions
すべての関数のエントリポイントと終了ポイントでユーザー指定のプロファイリング関数を呼び出すコードを追加します。
-ftrapv
こちらをご覧持ちですstackoverflow.com/questions/20851061/... ..長い固定を取得するために待っているバグがありますように思えます。
こちらが私のものです:
-Wextra
、-Wall
:必須。-Wfloat-equal
:通常、浮動小数点数が等しいかどうかをテストすることは悪いので便利です。-Wundef
:初期化されていない識別子が#if
ディレクティブで評価された場合に警告します。-Wshadow
:ローカル変数が別のローカル変数、パラメーター、またはグローバル変数をシャドウするとき、または組み込み関数がシャドウされるときは常に警告します。-Wpointer-arith
:関数またはのサイズに依存するものがあれば警告しvoid
ます。-Wcast-align
:必要なターゲットの配置が増加するようにポインターがキャストされたときに警告します。たとえば、整数が2バイトまたは4バイトの境界でのみアクセスできるマシンでにchar *
キャストされた場合に警告しint *
ます。-Wstrict-prototypes
:引数の型を指定せずに関数が宣言または定義されている場合に警告します。-Wstrict-overflow=5
:コンパイラーが符号付きオーバーフローが発生しないという前提に基づいて最適化する場合について警告します。(値5は厳しすぎる可能性があります。マニュアルページを参照してください。)-Wwrite-strings
:文字列定数に型のconst char[
長さを与えると]
、1のアドレスを非const char *
ポインターにコピーすると警告が出ます。-Waggregate-return
:構造体または共用体を返す関数が定義または呼び出された場合に警告します。-Wcast-qual
:ターゲット型から型修飾子を削除するためにポインターがキャストされるたびに警告します*。-Wswitch-default
:switch
ステートメントにdefault
大文字と小文字の区別がない場合は常に警告します*。-Wswitch-enum
:switch
ステートメントに列挙型のインデックスがありcase
、その列挙の名前付きコードの1つ以上のfor がない場合は常に警告します*。-Wconversion
:値を変更する可能性のある暗黙の変換について警告します*。-Wunreachable-code
:コンパイラがコードが実行されないことを検出した場合に警告します*。*が付いているものは、誤った警告を出すことが多いので、必要に応じて使用します。
-Wformat=2
:printf / scanf関数の追加のフォーマットチェック。
-Wall
ますか?
-Wwrite-strings
嫌いなので明示的にオフにする必要があることはわかっています。
-Wwrite-strings
、具体的には、それはの一部ではないと言う-Wall
:gcc.gnu.org/onlinedocs/gcc/...。多分あなたのセットアップの他の何かがそのフラグを設定していますか?または多分あなたはC ++をコンパイルしていますか?
常に使用-O
又は上記(-O1
、-O2
、-Os
、など)。デフォルトの最適化レベルでは、gccはコンパイル速度を優先し、一元化された変数などについて警告するのに十分な分析を行いません。
-Werror
コンパイルを停止しない警告は無視される傾向があるため、ポリシーの作成を検討してください。
-Wall
エラーである可能性が非常に高い警告をオンにします。
に含まれている警告は、-Wextra
一般的で正当なコードにフラグを付ける傾向があります。これらはコードレビューには役立ちますが(lintスタイルのプログラムでは、より多くの落とし穴がより柔軟であることがわかりますが)、通常の開発ではオンにしません。
-Wfloat-equal
プロジェクトの開発者が浮動小数点に慣れていない場合は良い考えですが、そうでない場合は悪い考えです。
-Winit-self
便利です。なぜ含まれていないのかしら-Wuninitialized
。
-Wpointer-arith
で動作しない大部分が移植可能なコードがある場合に便利です-pedantic
。
まだ誰もこれを言っていないことに驚いています-私にとって、最も有用なフラグ-g
は、デバッグ情報を実行可能ファイルに入れて、デバッグしてソースをステップスルーできるようにすることです(熟練していてアセンブリを読んでいる場合を除く)stepi
実行中のプログラムのコマンドのように)。
-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
-fmudflap
GCC 4.9以降はサポートされなくなりましたwarning: switch '-fmudflap' is no longer supported
。これは、AddressSanitizerに置き換えられました。
-march=native
コンパイルするプラットフォーム(=チップ)に最適化されたコードを生成する
コンパイラーによって事前定義されているプリプロセッサー・フラグを知る必要がある場合:
echo | gcc -E -dM -
エラーの検出にはあまり役立ちませんが、ほとんど言及されていない-masm=intel
オプションを使用すると、-S
すると、してアセンブリ出力を非常によく検査。
AT&Tアセンブリ構文は頭を痛めすぎます。
私のメイクファイルには通常、
CFLAGS= -Wall -Wextra -Weffc++ -Os -ggdb
...
g++ $(CFLAGS) -o junk $<
gcc $(CFLAGS) -o $@ $<
rm -f junk
これらのオプションの中で最も重要なものは前に説明されているので、まだ指摘されていない2つの機能を指摘します。
私がいることをコードベースに取り組んでいるにもかかわらず、ニーズは、いくつかのプラットフォームへの移植のために通常のCであることをまだ何もまともなC ++コンパイラを持っていない、私は(Cコンパイラに加えて)C ++コンパイラで「余分な」コンパイルを行います。これには3つの利点があります。
はい、私は絶望的に楽観的なPollyannaです。1つのプラットフォームが廃止されたと宣言されるか、まともなC ++コンパイラーを手に入れられるようになると、今月は確実にC ++に切り替えることができます。私の心の中で、それは避けられない-唯一の問題は、それが経営陣が最終的に全員にポニーを発行する前または後に起こるかどうかです。:-)
-Wstrict-prototypes -Wmissing-prototypes
-Wold-style-definition
、プロトタイプの宣言であっても、K&Rスタイルの関数が良いアイデアだと考える再犯者に対処する必要がある場合。(私はそのような人々に対処する必要があります。K&Rで記述された新しいコードを見つけると、それは本当に私を困らせます。修正されていないレガシーK&Rのものを持っていることは十分に悪いですが、新しいコードです!Grump !!!)
man gcc
マニュアルは、良い説明で興味深い旗でいっぱいです。ただし、-Wallはおそらくgccを可能な限り冗長にします。もっと興味深いデータが必要な場合は、valgrindまたはその他のエラーチェックツールを確認してください。
man gcc | nl
11000行を超えるレポート。それは悪名高いbash
マンページ以上のものです!
-M*
オプションのファミリー。
これらを使用すると、cまたはc ++ソースファイルがどのヘッダーファイルに依存する必要があるかを自動的に判断するmakeファイルを作成できます。GCCはこの依存関係情報を含むメイクファイルを生成し、プライマリメイクファイルからそれらをインクルードします。
以下は、-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
ある-Werror
すべての警告をエラーとして扱い、コンパイルを停止します、。gcc
マニュアルページには、お使いのコンパイラのすべてのコマンドラインスイッチについて説明します。
gcc
フラグはあなたのものと誰かが示唆するリンクとでは異なる場合があります。このため、ソフトウェアにマニュアルページが付属しています。
-Wfloat-equal
差出人:http : //mces.blogspot.com/2005/07/char-const-argv.html
私が好む他の新しい警告の1つは-Wfloat-equalです。これは、等価条件で浮動小数点数を[持っている]ときに必ず警告します。それは素晴らしいです!コンピュータグラフィックスまたは(悪い:)計算ジオメトリアルゴリズムをすべてプログラムした場合、2つのフロートが同等に一致することはありません...
特定の問題を修正するためのフラグを探しているこのスレッドを見つけました。ここには表示されないので、投稿で私を困らせていたものを追加します。
-Wformat=2
旗
-Wformat
=>printf
およびへの呼び出しscanf
などをチェックして、指定されたフォーマット文字列に適切なタイプの引数が提供されていることを確認してください...
そしてそれについての本当に重要な部分(GCCマニュアルによると):
-Wformat
に含まれてい-Wall
ます。形式チェックのいくつかの側面をより細かく制御するために、オプション-Wformat-y2k
、-Wno-format-extra-args
、-Wno-format-zero-length
、-Wformat-nonliteral
、-Wformat-security
、および-Wformat=2
利用可能ですが、-Wall.`に含まれていません
だから、あなたが持っているからと-Wall
いって、すべてを持っているというわけではありません。;)
私は時々-s
はるかに小さな実行可能ファイルを使用します:
-s
Remove all symbol table and relocation information from the executable.
出典:http : //gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options
strip
バイナリで実行する必要があります。これにより、デバッグ情報を含むバイナリを作成し、後で配布するために削除できます。
strip
動作しますが-s
、実行ほど複雑ではありませんが、速くて簡単ですstrip
この答えは少し話題から外れているかもしれませんが、質問は私からの価値ある+1です、なぜなら
偶発的なタイプの不一致を完全に最小限に抑えるために、追加の警告や、場合によっては警告をエラーに変換することに特に興味があります。すべてのエラーと明らかではない可能性のあるエラーをキャッチするツールがあります。gccや他のコンパイラーと比較して、IMHOがエラーをキャッチするのに優れた働きをする副子があります。それはあなたの道具箱に持つ価値のある道具です。
スプリントなどのlintタイプのツールによる静的チェックは、コンパイラツールチェーンの一部である必要があります。
追加の警告に特に興味があります。
に加えて-Wall
、-W
or -Wextra
オプション(-W
古いバージョンのgccだけでなく新しいバージョンのgccでも機能します。新しいバージョンでは代替名をサポートしています。-Wextra
これは同じ意味ですが、よりわかりやすくなっています)により、さまざまな追加の警告が有効になります。
これらのいずれによっても有効にされていない警告がさらにあります。使用可能なオプションのセットは、使用しているgccのバージョンによって異なります。詳細については、を参照するman gcc
かinfo gcc
、オンラインドキュメントを参照して、目的の特定のgccのバージョンを確認してください。また-pedantic
、使用されている特定の標準に必要なすべての警告を発行します(-std=xxx
または-ansi
)などの他のオプションで、gcc拡張機能の使用について不平を言います。
偶発的なタイプの不一致を最小限に抑えるために、警告をエラーに変換する場合もあります。
-Werror
すべての警告をエラーに変えます。ただし、gccでは特定の警告に対して選択的にそれを行うことができないと思います。
-Werror
外部ライブラリのヘッダーファイルがそれらの一部をトリップする可能性があるため、プロジェクトごとに有効にする警告(特にを使用する場合)を選択する必要があることに気付くでしょう。(-pedantic
特に、私の経験では、この点で役に立たない傾向があります。)
-Werror=some-warning
。
-Wmissing-prototypes
:前のプロトタイプ宣言なしでグローバル関数が定義されている場合。-Wformat-security
:起こり得るセキュリティの問題を表すフォーマット関数の使用について警告します。現在、これは、フォーマット文字列が文字列リテラルではなく、フォーマット引数がない関数への呼び出しprintf
とscanf
関数について警告します-Werror=return-type
:関数がgccに戻り値がない場合にエラーを強制します。それはある/we4716
のVisual Studioで。
-Werror=implicit-function-declaration
:定義されていない、または含まれていない関数を使用すると、エラーが発生します。それはある/we4013
のVisual Studioで。
-Werror=incompatible-pointer-types
:ポインターのタイプが予期されたポインタータイプと一致しない場合のエラー。それはある/we4133
のVisual Studioで。
実際、私は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()
-save-temps
、-Wshadow
そして-fmudflap
すべてのおかげで、私が知らなかった最大の発見でした。