__clang_major__
どうやら、Xcode にバンドルされている clang はアップストリームと値を尊重せず__clang_minor__
、代わりにある種の Xcode ユーザー向けバージョンを報告します。
参考までに、clang のさまざまな MacPorts インストールの値を次に示します。アップストリームのリリース ID を尊重しているようです。Linux でテストすると、同様の値が得られます。
➜ prohibit-clang-3.2 /opt/local/bin/clang++-mp-3.2 -dM -E -x c /dev/null |
grep __clang_m
#define __clang_major__ 3
#define __clang_minor__ 2
➜ prohibit-clang-3.2 /opt/local/bin/clang++-mp-3.3 -dM -E -x c /dev/null |
grep __clang_m
#define __clang_major__ 3
#define __clang_minor__ 3
➜ prohibit-clang-3.2 /opt/local/bin/clang++-mp-3.4 -dM -E -x c /dev/null |
grep __clang_m
#define __clang_major__ 3
#define __clang_minor__ 4
ただし、何らかの理由で、Apple が提供する clang には、ベースの clang リビジョンではなく、Xcode バージョンを追跡するバージョンが__clang_major__
あります。__clang_minor__
➜ prohibit-clang-3.2
/Applications/Xcode-4.6.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
-dM -E -x c /dev/null | grep __clang_m
#define __clang_major__ 4
#define __clang_minor__ 2
➜ prohibit-clang-3.2
/Applications/Xcode-4.6.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
--version
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix
➜ prohibit-clang-3.2
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
-dM -E -x c /dev/null | grep __clang_m
#define __clang_major__ 5
#define __clang_minor__ 0
➜ prohibit-clang-3.2
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
--version
Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix
➜ prohibit-clang-3.2 /usr/bin/clang++ -dM -E -x c /dev/null | grep __clang_m
#define __clang_major__ 5
#define __clang_minor__ 0
これは、Apple ベンダーの clang と、clang ソースまたはディストリビューション パッケージから通常ビルドされた clang の両方で正確に機能する、次のような条件付きコンパイル行を記述できないことを意味するため、かなりひどいようです。
#if !defined(__clang__) || (__clang_major__ > 3) || ((__clang_major__ == 3) && (__clang_minor__ > 2))
// Thing that doesn't work for clang-3.2 due to an optimization bug.
#endif
通常版と Apple 版の 2 つの異なる clang バージョン管理スキームを考慮して、すでにかなりひどいプリプロセッサ チェックを拡張する必要はありません。これが通常のclangではなく「Xcodeのclang」であることをどのように確実に検出できるかさえわかりません。
これを回避する方法について何か提案はありますか? 「真の」バージョンを報告するように指示するAppleのclangに渡すフラグはありますか? __clang_major__
それとも Apple は私たちにandを確実に使えないよう運命づけたのでしょ__clang_minor__
うか? これらは私がここで使用すべきマクロではありませんか?