2

foo.c に次のコードがある場合

#define P(x) printf("%s\n", #x)

void main() {
  P(3 == 4);
}

gcc -E foo.c を呼び出すと、次のように出力されます。

int main() {
  printf("%s\n", "3 == 4");
}

# 演算子がマクロ引数 x のリテラルを文字列化したことに注意してください。しかし、/usr/bin/cpp を呼び出すと、次のように表示され、正しく展開されません。

int main() {
  printf("%s\n", #3 == 4);
}
4

2 に答える 2

11

このcppコマンドはおそらく、準拠した C プリプロセッサとしてではなく、従来の ANSI C プリプロセッサとして動作しています。私の推測では、Darwin は BSD システムであり、C 以外の目的cpp(構成ファイルのマクロ処理など) でコマンドを使用する一部の壊れたレガシー BSD ソフトウェアは、適合する C に落とし込むと微妙な方法で壊れてしまうため、Apple がそのように機能させたのだと思います。その代わりにプリプロセッサ。

いずれにしても、cpp何が得られるかわからないため、このコマンドは使用しないでください。c99 -Eこれは、C プリプロセッサを呼び出す POSIX 準拠の方法であり、$CC -Eおそらく Makefile でそれを行う正しい方法です。

于 2012-03-01T00:55:07.280 に答える
5

何らかの理由で、cppオン ライオン (私はあなたと同じバージョンを持っています) が、-traditionalスイッチが有効になっているかのように動作するようです。他のバイナリ (Linux、FreeBSD) で観察した出力を再現できますが、スイッチcppを使用している場合のみです。-traditional

これを調査した結果/usr/bin/cpp、Mac OS X では次のように始まるスクリプトであることが判明しました。

#!/bin/sh
#
# Transitional front end to CCCP to make it behave like (Reiser) CCP:
#       specifies -traditional
#       doesn't search gcc-include

-traditionalこのスクリプトで指定された別のオプションを元に戻す方法は明らかにありません。1 つの回避策は、インストールされている特定のバージョン ( cpp-4.2. 私のシステムで使用cpp-4.2すると、目的の拡張が生成されます。

于 2012-03-01T05:28:01.050 に答える