gcc であらかじめ定義されているフラグ(マクロ)を調べる

毎週水曜日は'水'にちなんで、水泳部の日なのですが、なんだか体調がおもわしくないので帰ってしまいました。

仕事もたっぷりあるのですがね・・・> yanagibashi君ごめん!

さて、内輪の話はこれくらいにして、本日はgccであらかじめ定義されているフラグ(マクロ)を調べる方法をご紹介いたします。

C/C++プログラマなら、ソースの機種依存部をプリプロセッサの#ifdefディレクティブで分岐させることはよくあると思います。

例:


#ifdef LINUX
if ((fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1 ) {
perror("socket");
}
#endif
#ifdef SVR
/* DLPI を使ったむづかしぃしょり */
#endif

こうした方法は手軽ですが、Makefile内部でプリプロセッサに—DLINUXや—DSVRなどと指定をしてあげないと行けないので、ちょっと面倒です。(autoconf 云々は小規模なプログラムでは面倒)

そこで、あらかじめシステムで定義されているフラグを使えば便利だと思いませんか?

例ではLINUXSVRとしているところを、__linux__ や __svr4__ としてあげれば、普通にターゲットで gcc するだけで目的のコードがコンパイルされます。

では、どうやってこの __linux__ や __svr4__ なんて言うあらかじめ定義されたフラグを知るかと言いますと・・・

gcc には -dM というオプションがあります。man を読むと、

プリプロセッサに対して、プリプロセス終了時に有効であったマクロの定義のみを出力するように 指示します。'-E’オプションとともに使用します。

今回の目的が達成できそうなことが書いてあります!(日本語 man バンザイ)

しかし実際にリストをえるためだけに実行してみると。。。


mtaneda@niconico:~% gcc -dM -E
gcc: no input files

と、とても寂しい結果になってしまいます。

まぁ no input と言われるなら input してあげましょう。


mtaneda@niconico:~% cat > hello.c
main() { printf("Hello, world!\n"); }
^D
mtaneda@niconico:~% gcc -dM -E hello.c
#define __DBL_MIN_EXP__ (-1021)
#define __FLT_MIN__ 1.17549435e-38F
〜ずらずら〜

出ました出ました。これらがプリプロセス時に自動的に付加されるマクロです。 しかし、いちいち何かファイルを指定するのも面倒です。そんなときは、-x c /dev/null (c は言語指定なので別に c++ でも良い) を hello.c のかわりに指定します。


mtaneda@niconico:~% gcc -dM -E -c /dev/null
#define __DBL_MIN_EXP__ (-1021)
#define __FLT_MIN__ 1.17549435e-38F
〜ずらずら〜

めでたしめでたし。