哪个跨平台预处理器定义? (__ WIN32__或__WIN32或WIN32)?

时间:2010-06-07 13:16:16

标签: c++ macros c-preprocessor

我经常看到__WIN32WIN32__WIN32__。我认为这取决于使用的预处理器(来自visual studio或gcc等)。

我现在必须首先检查os,然后检查使用过的编译器吗?我们在这里使用的是G ++ 4.4.x,Visual Studio 2008和Xcode(我假设它是gcc)和ATM我们只使用__WIN32____APPLE____LINUX__

5 个答案:

答案 0 :(得分:36)

本文回答了您的问题:

这篇文章篇幅很长,包括难以复制的表格,但这就是本质:

您可以使用以下方法检测Unix风格的操作系统:

#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 with:

#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

Windows with Cygwin

#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__,{{ 1}},__MINGW32____MINGW64____NetBSD____OpenBSD___POSIX_IPV6_POSIX_MAPPED_FILES_POSIX_SEMAPHORES,{{1} },_POSIX_THREADS_POSIX_VERSIONsun__sun__SunOS__sun____SVR4__svr4__TARGET_IPHONE_SIMULATORTARGET_OS_EMBEDDEDTARGET_OS_IPHONETARGET_OS_MACUNIXunix__unix__unix__,{{ 1}},WIN32_WIN32__WIN32__WIN32__WIN64_WIN64__WIN64,{{1} }。

related articlearchive.org link)涵盖检测编译器和编译器版本。它列出了以下符号:__WIN64__WINNT__WINNT__WINNT____clang____GNUC____GNUG__,{{ 1}},__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__,{{ 1}},__GNUC_PATCHLEVEL____GNUC____GNUG____HP_aCC__HP_cc__IBMCPP____IBMC__,{{1} },__ICC__INTEL_COMPILER__INTEL_COMPILER_BUILD_DATE_MSC_BUILD_MSC_FULL_VER_MSC_VER__PGIC_MINOR____PGIC_PATCHLEVEL__检测编译器版本。

答案 1 :(得分:14)

这取决于你想要做什么。如果您的程序想要使用某些特定的函数(例如,来自gcc工具链),您可以检查编译器。如果要使用某些特定于操作系统的函数(无论编译器是什么 - 例如Windows上的CreateProcess和unix上的fork),您可以检查操作系统(_WINDOWS,__ unix__)。

Macros for Visual C

Macros for gcc

您必须检查每个编译器的文档,以便能够在编译时检测差异。我记得gnu工具链(gcc)在C库(libc)中有一些不在其他工具链上的函数(比如Visual C)。这样,如果您想要使用商品以外的那些功能,那么您必须检测到您正在使用GCC,因此您必须使用的代码如下:

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

答案 2 :(得分:3)

不明白你为什么这么做。您可能必须记住在编译器的命令行上手动指定定义,但这就是全部。对于记录,Visual Studio的定义是_WIN32(带有一个下划线)而不是__WIN32。如果它没有定义那么它没有定义,也没关系。

答案 3 :(得分:2)

我重建了我的答案......该死的,编辑狂暴:P:

您不需要使用部分的。可能对于MacOSX,Linux和其他类似Unix的东西,你根本不需要使用任何东西。

最受欢迎的是(据Google说实话)_WIN32

从不在源代码中“手动”定义它。它以下列方式之一定义:
作为命令行预处理器/编译器标志(如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。然后,您需要在编译时设置适当的预处理器定义(使用-D标志使用gcc,例如。gcc -D _WIN32)。

如果您不编写任何与平台相关的代码,那么您不需要关心这样的#ifdef, #else, #endif块。大多数Windows编译器/预处理器AFAIK已经预定义了一些符号,如_WIN32(最流行的,据谷歌说实话),WIN32_WIN32_等。所以在Windows上编译它最有可能的是,除了编译之外,你不需要做任何其他事情。

答案 4 :(得分:0)

叹息 - 不要依赖编译器 - 在Makefile中指定要构建的平台。简而言之,以_开头的任何内容都取决于实现,而不是可移植的

我曾经尝试过你的方法,在一个非常大的项目上,在Sun-C ++和GCC之间徘徊,我们决定采用Makefile控制,而不是试图推断编译器将要做什么。