プリプロセッサマクロからプラットフォーム/コンパイラを識別する方法


115

私はLinux、Windows、Mac OSでコンパイルできるクロスプラットフォームコードを書いています。Windowsでは、ビジュアルスタジオとmingwをサポートする必要があります。

プラットフォーム固有のコードがいくつかありますが、これを#ifdef .. #endif環境に配置する必要があります。たとえば、ここではwin32固有のコードを配置しました。

#ifdef WIN32
#include <windows.h>
#endif

しかし、どうすればLinuxとMac OSを認識できますか?使用すべき定義名(など)は何ですか?


3
こちらがOSマクロ定義リストです。
OCaml 2012

だまされた方がはるかによく受け入れられた答えを持っています。
rubenvb

1
提案された複製は同じ質問ではありません。この質問では、オペレーティングシステムの識別についてのみ質問しますが、この質問では、コンパイラの識別についても質問します。これは非常に異なることです。
JBentley 2014年

@JBentleyでも、受け入れられた回答ではコンパイラについては言及されておらず、OS(および1つの「プラットフォーム」)についてのみ言及しています。言うまでもなく、それは、だまされた人が何を提供しなければならないかに関して、ひどい答えです。
rubenvb 2015年

1
@rubenvb次に、他の質問をコメントとしてリンクします。それがより良い答えを持っているからといって、それを複製にしないでください。問題は、それが答えではなく、それが重複であるかどうかを決定するものです。これを閉じるだけで、コンパイラー関連の質問に対する質の高い答えが得られないことが保証されます。これは、いわゆる「重複」が答えることはできません。
JBentley、2015年

回答:


133

以下のためのMacのOS

#ifdef __APPLE__

Windows上のMingWの場合:

#ifdef __MINGW32__

以下のためのLinux

#ifdef __linux__

他のWindowsのコンパイラの場合は、チェックこのスレッド、これを他のいくつかのコンパイラおよびアーキテクチャで。


2
__APPLE__OSXとiOSを区別?
gman、

14
__APPLE__OS XとiOSの両方に設定されます。あなたは#include <TargetConditionals.h>中に入ることができ#ifdef __APPLE__ますTARGET_OS_IPHONE #define
Ted Mielczarek、2011

2
__MINGW64__mingw64を使用している場合にも利用できます
スコーン

2
__MINGW64__が参照されているので_MSC_VER、Windows / MSVCについて言及する価値があると考えてください(MSVCバージョンの確認にも使用できます)。
ideasman42 14

申し訳ありませんが、この答えはすべてのアカウントでかなり間違っており、質問にも答えていません。
rubenvb 2015年

59

参照:http : //predef.sourceforge.net/index.php

このプロジェクトは、#defines多くのオペレーティングシステム、コンパイラ、言語とプラットフォームの標準、および標準ライブラリ用に事前定義された、かなり包括的なリストを提供します。


5
バージョン1.55以降、PredefはBoost C ++ Librariesに含まれるようになりました。
右辺値

あなたがこれを投稿したときのルールは異なっていたと思いますが、この投稿を編集してより関連性の高い詳細を含めるようにお願いする必要があります。今日、リンクのみの回答はお勧めできません。削除する前にこの投稿を保存する機会を提供したいと思います。
Mick MacCallum 14

1
これはタイトルに記載されている質問に実際に回答する唯一の回答であり、質問は非常に一般的で関連性があるため、削除しないよう強くお勧めします。私はそれを「リンクのみ」の答えとは呼びません。
ホブ2014

2
@ 0x7fffffff:他の回答の内容をこの回答に複製すると、誰にとってもどのようなメリットがありますか?明確な回答を1つにすることが非常に重要であると考える場合は、そのような回答を自分で作成することをお勧めします(難しいことではありません。既存の回答を賢明な順序で結合してください)。個人的には自分の時間との関係はもっと良いですが、モデレーターとして明らかに私よりもSOの方があなたにとって重要です。
John Bartholomew、

47

これが私が使うものです:

#ifdef _WIN32 // note the underscore: without it, it's not msdn official!
    // Windows (x64 and x86)
#elif __unix__ // all unices, not all compilers
    // Unix
#elif __linux__
    // linux
#elif __APPLE__
    // Mac OS, not sure if this is covered by __posix__ and/or __unix__ though...
#endif

編集:上記は基本的には機能するかもしれませんが、Boost.Predefのリファレンスページを確認して、確認するマクロを確認してください。または、直接Boost.Predefを使用します。


4
代わりに__linux __を使用してください。GNU拡張を無効にしてGCCでコンパイルする場合、Linuxは定義されません(つまり、-std = c ++ 0x)
Erburethは、モニカ

1
@Erbureth修正済みですが、実際には、最高評価の回答のようにpredef.sourceforge.net/index.phpを使用する必要があります。
rubenvb

@rubenvb:確かに。それでも投票数は少なすぎると思います。:) ...私は何度も彼らのサイトに行きました。
0xC0000022L

一貫性を保つため(おそらく少し知識が豊富です):最初に#if定義されているかどうかを確認し、他のユーザーは値をテストします。より一貫性のある場合#elif defined(__unix__) など、私は思います。
leonbloy

20

C ++を作成している場合、Boostの使用はお勧めできませんライブラリを十分に強く。

最新バージョン(1.55)には、探しているものを正確にカバーする新しいPredefライブラリと、他の何十ものプラットフォームおよびアーキテクチャ認識マクロが含まれています。

#include <boost/predef.h>

// ...

#if BOOST_OS_WINDOWS

#elif BOOST_OS_LINUX

#elif BOOST_OS_MACOS

#endif

これがブーストであることを考えると、このソリューションはさまざまなプラットフォーム/ OSとさまざまなコンパイラで動作します。
Trevor Boyd Smith

3
「Boostライブラリの使用を強く推奨することはできません...」 -Boostを3回評価しました。評価に合格できません...バグレポートのほとんどは、認められれば幸運でした。承認の欠如は、エンジニアリングプロセスのより深い問題を示しています。プリプロセッサマクロと組み込みのC ++標準ライブラリの方が安全な選択だと思います。
jww 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.