web-dev-qa-db-ja.com

どのクロスプラットフォームプリプロセッサが定義していますか? (__WIN32__または__WIN32またはWIN32)?

よく見る__WIN32WIN32または__WIN32__。これは、使用されているプリプロセッサ(Visual Studioからのプリプロセッサ、またはgccなど)に依存すると想定しています。

最初にosをチェックし、次に使用したコンパイラをチェックする必要がありますか?ここではG ++ 4.4.x、Visual Studio 2008およびXcode(これもgccであると想定しています)とATMを使用しています__WIN32____Apple__および__LINUX__

38
math

何をしようとしているのかによります。プログラムが特定の機能を使用したい場合は、コンパイラーをチェックできます(例えば、gccツールチェーンから)。 OS固有の機能を使用する場合は、オペレーティングシステム(_WINDOWS、__ unix__)を確認できます(コンパイラーに関係なく-たとえば、WindowsのCreateProcessとUNIXのfork)。

Visual Cのマクロ

gccのマクロ

コンパイル時に違いを検出できるようにするには、各コンパイラのドキュメントを確認する必要があります。 gnu toolchain(gcc)には、Cライブラリ( libc )に他のツールチェーン(たとえばVisual Cなど)にない関数がいくつかあることを覚えています。この方法で、これらの機能を汎用的に使用する場合は、GCCを使用していることを検出する必要があるため、使用する必要があるコードは次のようになります。

#ifdef __GNUC__
// do my gcc specific stuff
#else
// ... handle this for other compilers
#endif
15
INS

この記事はあなたの質問に答えます:

この記事は非常に長く、再現が難しい表が含まれていますが、ここにその本質があります。

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_linuxhpux__hpuxlinux__linux__linux____MACH____MINGW32____MINGW64____NetBSD____OpenBSD___POSIX_IPV6_POSIX_MAPPED_FILES_POSIX_SEMAPHORES_POSIX_THREADS_POSIX_VERSIONSun__Sun__SunOS__Sun____SVR4__svr4__TARGET_IPHONE_SIMULATORTARGET_OS_EMBEDDEDTARGET_OS_IPHONETARGET_OS_MACUNIXunix__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__コンパイラのバージョンを検出します。

40
Charphacy

なぜそうなのかわからない。コンパイラのコマンドラインで定義を手動で指定することを覚えておく必要があるかもしれませんが、それだけです。レコードの場合、Visual Studioの定義は_WIN32ではなく __WIN32 (アンダースコアが1つ)です。定義されていない場合は定義されていないため、問題ではありません。

3
Billy ONeal

私は答えを再構築しました...くそー、編集凶暴な: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_などのようないくつかのシンボルを事前に定義しています。ほとんどの場合、コンパイルする以外に何も作成する必要はありません。

2
silmeth

ため息-コンパイラに依存しないでください-Makefileで構築するプラットフォームを指定してください。簡単に言えば、_で始まるものはすべて実装に依存しており、移植性がありません。

昔々、非常に大規模なプロジェクトであなたの方法を試しましたが、Sun-C++とGCCの間で跳ね回る間に、コンパイラが何をしようとしているかを推測するのではなく、Makefileコントロールを使用することにしました。

0
Chris K