よく見る__WIN32
、WIN32
または__WIN32__
。これは、使用されているプリプロセッサ(Visual Studioからのプリプロセッサ、またはgccなど)に依存すると想定しています。
最初にosをチェックし、次に使用したコンパイラをチェックする必要がありますか?ここではG ++ 4.4.x、Visual Studio 2008およびXcode(これもgccであると想定しています)とATMを使用しています__WIN32__
、__Apple__
および__LINUX__
。
何をしようとしているのかによります。プログラムが特定の機能を使用したい場合は、コンパイラーをチェックできます(例えば、gccツールチェーンから)。 OS固有の機能を使用する場合は、オペレーティングシステム(_WINDOWS、__ unix__)を確認できます(コンパイラーに関係なく-たとえば、WindowsのCreateProcessとUNIXのfork)。
コンパイル時に違いを検出できるようにするには、各コンパイラのドキュメントを確認する必要があります。 gnu toolchain(gcc)には、Cライブラリ( libc )に他のツールチェーン(たとえばVisual Cなど)にない関数がいくつかあることを覚えています。この方法で、これらの機能を汎用的に使用する場合は、GCCを使用していることを検出する必要があるため、使用する必要があるコードは次のようになります。
#ifdef __GNUC__
// do my gcc specific stuff
#else
// ... handle this for other compilers
#endif
この記事はあなたの質問に答えます:
この記事は非常に長く、再現が難しい表が含まれていますが、ここにその本質があります。
UnixスタイルのOSは次の方法で検出できます。
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__Apple__) && defined(__MACH__)))
/* UNIX-style OS. ------------------------------------------- */
#endif
Unixであることがわかったら、次のコマンドでPOSIXとPOSIXバージョンかどうかを確認できます。
#include <unistd.h>
#if defined(_POSIX_VERSION)
/* POSIX compliant */
#endif
以下を使用して、BSD派生システムを確認できます。
#if defined(__unix__) || (defined(__Apple__) && defined(__MACH__))
#include <sys/param.h>
#if defined(BSD)
/* BSD (DragonFly BSD, FreeBSD, OpenBSD, NetBSD). ----------- */
#endif
#endif
およびLinux
#if defined(__linux__)
/* Linux */
#endif
appleのオペレーティングシステム
#if defined(__Apple__) && defined(__MACH__)
/* Apple OSX and iOS (Darwin) */
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR == 1
/* iOS in Xcode simulator */
#Elif TARGET_OS_IPHONE == 1
/* iOS on iPhone, iPad, etc. */
#Elif TARGET_OS_MAC == 1
/* OS X */
#endif
#endif
Cygwinを使用したWindows
#if defined(__CYGWIN__) && !defined(_WIN32)
/* Cygwin POSIX under Microsoft Windows. */
#endif
また、以下の非POSIX Windows:
#if defined(_WIN64)
/* Microsoft Windows (64-bit) */
#Elif defined(_WIN32)
/* Microsoft Windows (32-bit) */
#endif
記事全文には、以下のシンボルがリストされ、どのシステムがそれらを定義するか、いつ:_AIX
、__Apple__
、__CYGWIN32__
、__CYGWIN__
、__DragonFly__
、__FreeBSD__
、__gnu_linux
、hpux
、__hpux
、linux
、__linux
、__linux__
、__MACH__
、__MINGW32__
、__MINGW64__
、__NetBSD__
、__OpenBSD__
、_POSIX_IPV6
、_POSIX_MAPPED_FILES
、_POSIX_SEMAPHORES
、_POSIX_THREADS
、_POSIX_VERSION
、Sun
、__Sun
、__SunOS
、__Sun__
、__SVR4
、__svr4__
、TARGET_IPHONE_SIMULATOR
、TARGET_OS_EMBEDDED
、 TARGET_OS_IPHONE
、TARGET_OS_MAC
、UNIX
、unix
、__unix
、__unix__
、WIN32
、_WIN32
、 __WIN32
、__WIN32__
、WIN64
、_WIN64
、__WIN64
、__WIN64__
、WINNT
、__WINNT
、__WINNT__
。
関連記事 ( archive.org link )は、コンパイラーとコンパイラーのバージョンの検出について説明しています。 __clang__
、__GNUC__
、__GNUG__
、__HP_aCC
、__HP_cc
、__IBMCPP__
、__IBMC__
、__ICC
、__INTEL_COMPILER
、_MSC_VER
、__PGI
、__SUNPRO_C
、__SUNPRO_CC
、コンパイラー検出用、および__clang_major__
、__clang_minor__
、 __clang_patchlevel__
、__clang_version__
、__GNUC_MINOR__
、__GNUC_PATCHLEVEL__
、__GNUC__
、__GNUG__
、__HP_aCC
、__HP_cc
、__IBMCPP__
、__IBMC__
、__ICC
、__INTEL_COMPILER
、__INTEL_COMPILER_BUILD_DATE
、_MSC_BUILD
、_MSC_FULL_VER
、_MSC_VER
、__PGIC_MINOR__
、__PGIC_PATCHLEVEL__
、__PGIC__
、__SUNPRO_C
、__SUNPRO_CC
、__VERSION__
、__xlC_ver__
、__xlC__
、__xlc__
コンパイラのバージョンを検出します。
なぜそうなのかわからない。コンパイラのコマンドラインで定義を手動で指定することを覚えておく必要があるかもしれませんが、それだけです。レコードの場合、Visual Studioの定義は_WIN32
ではなく __WIN32
(アンダースコアが1つ)です。定義されていない場合は定義されていないため、問題ではありません。
私は答えを再構築しました...くそー、編集凶暴な:P:
部分的なものを使用する必要はありません。そしておそらく、MacOSX、Linux、および他のUnixライクの場合、まったく使用する必要はありません。
最も人気のあるものは(Googleが真実を伝える限り)_WIN32
です。
neverソースコードで「手動」で定義します。次のいずれかの方法で定義されます。
コマンドラインプリプロセッサ/コンパイラフラグとして(g++ -D _WIN32
など)
またはコンパイラー自体によって事前定義されています(ほとんどのWindowsコンパイラーは、_WIN32
、および場合によってはWIN32
や_WIN32_
などの事前定義もします。すべて定義することを心配して、コンパイラはすべての作業を行います。
そして私の古い答え:
あなたは何もする必要はありません。マルチプラットフォームの互換性のためだけです。多くの場合、すべてのUnixライク(Linux、MacOSX、BSD、Solarisなど)およびその他のPOSIXプラットフォームのコードのバージョンは完全に同じであり、Windowsにはいくつかの変更が必要です。そのため、一般的にUnixライクなコードを記述し、#ifdef _WIN32
と#endif
の間にWindows専用(DirectX命令、Windowsライクなファイルパスなど)の部分を配置します。
いくつかの部品がある場合。 X-Windowシステムのみ、またはMacOSのみの場合、#ifdef X_WINDOW
や#ifdef MACOS
のようなものを使用して同様の操作を行います。次に、コンパイル時に適切なプリプロセッサ定義を設定する必要があります(たとえば、gcc -D _WIN32
などの-Dフラグを使用したgccを使用)。
プラットフォーム依存のコードを記述しない場合、そのような#ifdef, #else, #endif
ブロックを気にする必要はありません。そして、ほとんどのWindowsコンパイラ/プリプロセッサは、_WIN32
(Googleが真実を伝える限り最も人気があります)、WIN32
、_WIN32_
などのようないくつかのシンボルを事前に定義しています。ほとんどの場合、コンパイルする以外に何も作成する必要はありません。
ため息-コンパイラに依存しないでください-Makefileで構築するプラットフォームを指定してください。簡単に言えば、_で始まるものはすべて実装に依存しており、移植性がありません。
昔々、非常に大規模なプロジェクトであなたの方法を試しましたが、Sun-C++とGCCの間で跳ね回る間に、コンパイラが何をしようとしているかを推測するのではなく、Makefileコントロールを使用することにしました。