Gcc/g ++がコマンドラインからプリプロセッサ定義をダンプする方法はありますか? __GNUC__
、__STDC__
などのようなものを意味します。
はい、-cの代わりに-E -dM
オプションを使用します。例(標準出力に出力):
gcc -dM -E - < /dev/null
C++の場合
g++ -dM -E -x c++ - < /dev/null
gccマニュアル から:
通常の出力の代わりに、プリプロセッサの実行中に定義されたすべてのマクロ(定義済みマクロを含む)の `#define 'ディレクティブのリストを生成します。これにより、プリプロセッサのバージョンで事前に定義されているものを見つけることができます。ファイルfoo.hがないと仮定すると、コマンド
touch foo.h; cpp -dM foo.h
すべての定義済みマクロが表示されます。
-Eオプションなしで-dMを使用すると、-dMは-fdump-rtl-machの同義語として解釈されます。
私は通常次のようにそれをします:
$ gcc -dM -E - < /dev/null
一部のプリプロセッサ定義はコマンドラインオプションに依存していることに注意してください-上記のコマンドラインに関連オプションを追加することでこれらをテストできます。たとえば、デフォルトで有効になっているSSE3/SSE4オプションを確認するには:
$ gcc -dM -E - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSSE3__ 1
-msse4
が指定されている場合、これを比較します。
$ gcc -dM -E -msse4 - < /dev/null | grep SSE[34]
#define __SSE3__ 1
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSSE3__ 1
同様に、コマンドラインオプションの2つの異なるセット間で異なるオプションを確認できます。最適化レベル-O0
(なし)および-O3
(完全)のプリプロセッサー定義の比較:
$ gcc -dM -E -O0 - < /dev/null > /tmp/O0.txt
$ gcc -dM -E -O3 - < /dev/null > /tmp/O3.txt
$ sdiff -s /tmp/O0.txt /tmp/O3.txt
#define __NO_INLINE__ 1 <
> #define __OPTIMIZE__ 1
後期回答-他の回答が有用であることがわかりました-そして、少し余分に追加したいと思いました。
特定のヘッダーファイルからのプリプロセッサマクロをダンプするにはどうすればよいですか?
echo "#include <sys/socket.h>" | gcc -E -dM -
特に、システムでSOMAXCONNが定義されているものを確認したかった。標準のヘッダーファイルを開くだけでよいことはわかっていますが、ヘッダーファイルの場所を見つけるために少し検索する必要がある場合があります。代わりに、このワンライナーを使用できます。
$ echo "#include <sys/socket.h>" | gcc -E -dM - | grep SOMAXCONN
#define SOMAXCONN 128
$
単純なアプローチ(gcc -dM -E - < /dev/null
)はgccでは正常に機能しますが、g ++では失敗します。最近、C++ 11/C++ 14機能のテストが必要になりました。対応するマクロ名の推奨事項は、 https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations で公開されています。しかし:
g++ -dM -E - < /dev/null | fgrep __cpp_alias_templates
silentがCドライバを(gcc
によって呼び出されるかのように)呼び出すため、常に失敗します。これを確認するには、出力をgccの出力と比較するか、エラーメッセージcc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C
を出力する(-std = c ++ 11)などのg ++固有のコマンドラインオプションを追加します。
(非C++)gccはneverが「テンプレートエイリアス」をサポートするため( http://www.open-std.org/を参照) jtc1/sc22/wg21/docs/papers/2007/n2258.pdf )C++コンパイラーの呼び出しを強制するには-x c++
オプションを追加する必要があります(空のダミーファイルの代わりに-x c++
オプションを使用するためのクレジットはyuyichaoに移動し、下記参照):
g++ -dM -E -x c++ /dev/null | fgrep __cpp_alias_templates
G ++(リビジョン4.9.1、デフォルトは-std = gnu ++ 98)はデフォルトでC++ 11機能を有効にしないため、出力はありません。そのためには、次を使用します
g++ -dM -E -x c++ -std=c++11 /dev/null | fgrep __cpp_alias_templates
最終的に得られます
#define __cpp_alias_templates 200704
g ++ 4.9.1は、-std=c++11
で呼び出されたときに「テンプレートエイリアス」をサポートすることに注意してください。
LinuxまたはWindows(/ dev/nullがない場合)でも同様に機能する移植可能なアプローチ:
echo | gcc -dM -E -
C++の場合は、使用できます(c++11
を使用するバージョンに置き換えてください):
echo | gcc -x c++ -std=c++11 -dM -E -
Gccにstdin(エコーによって生成される)を前処理し、 すべてのプリプロセッサ定義を出力 (-dletters
を検索)することで機能します。ヘッダーファイルをインクルードするときに、定義がaddedであるかを知りたい場合は、-dMに似ていますが、定義済みマクロを含まない-dD
オプションを使用できます:
echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -
ただし、空の入力では-dD
オプションを使用して多くの定義が生成されることに注意してください。
複雑なビルドシステムがあり、gcc/g ++コマンドを直接取得(または変更)するのが難しい大きなプロジェクトで作業しているとき、マクロ展開の結果を確認する別の方法があります。マクロを再定義するだけで、次のような出力が得られます。
file.h: note: this is the location of the previous definition
#define MACRO current_value