GCCダンププリプロセッサが定義


回答:


304

はい、-E -dM-cの代わりにオプションを使用します。例(それらをstdoutに出力します):

 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の同義語として解釈されます。


4
gccは、/ dev / nullが何も意味しないシステムに存在します。
Pavel P

4
@Pavelでは、gccまたはプリプロセッサ-cppのいずれかで空のファイルを使用できます。
慈善家、2014年

16
代わりの答えとして、よりポータブルなアプローチを追加しましたecho | gcc -dM -E -。Windowsでも機能します。
Pavel P

4
これらの定義がどこから(つまりどのファイルで)作成されたかを判断することは可能ですか?
edam 2014

2
または、Windowsでは、cpp -dM -E - < NULを使用できます。
ルネNyffenegger

78

私は通常このようにします:

$ 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

45

遅い答え-他の答えは有用だと思いました-もう少し追加したかったです。


特定のヘッダーファイルからのプリプロセッサマクロをダンプするにはどうすればよいですか?

echo "#include <sys/socket.h>" | gcc -E -dM -

または(提案のために@mymediaに感謝):

gcc -E -dM -include sys/socket.h - < /dev/null

特に、システムでSOMAXCONNがどのように定義されているかを確認したいと思いました。標準のヘッダーファイルを開くことができることはわかっていますが、ヘッダーファイルの場所を見つけるために少し検索する必要がある場合があります。代わりに、このワンライナーを使用できます。

$ gcc -E -dM -include sys/socket.h - < /dev/null | grep SOMAXCONN
#define SOMAXCONN 128
$ 

1
-includeコンパイラー・オプションを使用してパイプを回避できます
mymedia

31

シンプルなアプローチ(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

サイレントモードでCドライバを呼び出すため、常に失敗します(まるでによって呼び出されたかのようにgcc)。これは、出力をgccの出力と比較するか、エラーメッセージを出力する(-std = c ++ 11)のようなg ++固有のコマンドラインオプションを追加することで確認できますcc1: warning: command line option ‘-std=c++11’ is valid for C++/ObjC++ but not for C

(非C ++)gccは「テンプレートエイリアス」をサポートしないため(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdfを参照)、次の-x c++オプションを追加する必要があります。 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


7
ダミーファイルを使用する必要はありません。GCCはこの-x議論を支持するので、g++ -x c++ -dM -E -std=c++11 - < /dev/null | grep cppうまくいくはずです。
yuyichao 2015

@yuyichaoありがとう、これにより使いやすくなります。私は-xオプションを知らなかった。あなたのコメントに賛成し、元の回答に統合しました。
ヘルマンク2015

23

LinuxまたはWindows(/ dev / nullがない場合)でも同じように機能する移植可能なアプローチ:

echo | gcc -dM -E -

c ++の場合c++11、次のように使用できます(使用するバージョンに置き換えてください)。

echo | gcc -x c++ -std=c++11 -dM -E -

これは、gccにstdin(echoによって生成される)を前処理し、すべてのプリプロセッサー定義を出力するように指示することによって機能します(検索-dletters)。ヘッダーファイルをインクルードするときに追加される定義を知りたい場合は、-dD-dMと同様のオプションを使用できますが、事前定義されたマクロは含まれません。

echo "#include <stdlib.h>" | gcc -x c++ -std=c++11 -dD -E -

ただし、空の入力でも-dDオプション付きの定義が多数生成されることに注意してください。


6
@rubenvbそれは無関係です。重要なのは、少なくともWindowsとUNIXで同等に機能するcmd行を用意することです。を使用するとNUL、元のサイズに戻ります。それがないシステムでは機能しません。
Pavel P

2
Cのための完全な答えを追加する++、(が、WindowsとLinuxの両方で動作sort少し異なる振る舞い):echo | gcc -x c++ -std=c++17 -dM -E - | sort
Xeverous

これにより、git-bashで空の出力が生成されます。
Lennart Rolland

@LennartRollandそれはgccを持っていますか?私のgit-bashではgccを実行できません
Pavel P

@pavel Windows用のQt5バイナリ配布に付属しているmingw32 gccを使用しています。
Lennart Rolland

3

ビルドシステムが複雑で、gcc / g ++コマンドを直接取得(または変更)するのが難しい大きなプロジェクトで作業しているときに、マクロ展開の結果を確認する別の方法があります。マクロを再定義するだけで、次のような出力が得られます。

file.h: note: this is the location of the previous definition
#define MACRO current_value

そのために使用されている警告フラグを探しています。あなたは知っていますか ?
Welgriv
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.