如何在C预处理器中可靠地检测Mac OS X,iOS,Linux,Windows?

Eon*_*nil 291 c c++ cross-platform c-preprocessor os-detection

如果有一些跨平台的C/C++代码应该在Mac OS X,iOS,Linux,Windows上编译,我如何在预处理器进程中可靠地检测它们?

Evg*_*rin 479

大多数编译器都使用预定义的宏,您可以在此处找到列表.可以在此处找到GCC编译器预定义的宏.这是gcc的一个例子:

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
   //define something for Windows (32-bit and 64-bit, this part is common)
   #ifdef _WIN64
      //define something for Windows (64-bit only)
   #else
      //define something for Windows (32-bit only)
   #endif
#elif __APPLE__
    #include <TargetConditionals.h>
    #if TARGET_IPHONE_SIMULATOR
         // iOS Simulator
    #elif TARGET_OS_IPHONE
        // iOS device
    #elif TARGET_OS_MAC
        // Other kinds of Mac OS
    #else
    #   error "Unknown Apple platform"
    #endif
#elif __linux__
    // linux
#elif __unix__ // all unices not caught above
    // Unix
#elif defined(_POSIX_VERSION)
    // POSIX
#else
#   error "Unknown compiler"
#endif
Run Code Online (Sandbox Code Playgroud)

定义的宏取决于您将要使用的编译器.

_WIN64 #ifdef可嵌套到_WIN32 #ifdef,因为_WIN32针对Windows,不仅在x86版本时被定义.如果某些包含对两者都是通用的,则可以防止代码重复.

  • 还有更多...它应该是`#if TARGET_OS_IPHONE`而不是`#ifdef`,因为在Mac上将`TARGET_OS_IPHONE`定义为'0`. (9认同)
  • @Paul,"代码应该在Mac OS X,iOS,Linux,Windows上编译" (5认同)
  • @jdknight是`__linux__`是所有Linux发行版上支持的宏,所有Linux发行版都不支持`__linux`,出于同样的原因,`__ unix__`也应该用来代替`__unix`,因为所有平台都遵循unix指南支持`__ unix__`,而不是`__unix`,这里有更深入的描述http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system (5认同)
  • 还要添加`__ANDROID__` (4认同)
  • 根据SourceForge _WIN32是为32和64位版本的Windows定义的,所以不应该_WIN64放在_WIN32之前? (2认同)
  • 我还会在 `__linux__` 上方添加 `__ANDROID__` 以确保完整性,因为与 Linux 相比,它有自己的细节。 (2认同)

Pat*_*Fog 29

正如Jake所指出的,TARGET_IPHONE_SIMULATOR是TARGET_OS_IPHONE的子集.

此外,TARGET_OS_IPHONE是TARGET_OS_MAC的子集.

所以更好的方法可能是:

#ifdef _WIN64
   //define something for Windows (64-bit)
#elif _WIN32
   //define something for Windows (32-bit)
#elif __APPLE__
    #include "TargetConditionals.h"
    #if TARGET_OS_IPHONE && TARGET_IPHONE_SIMULATOR
        // define something for simulator   
    #elif TARGET_OS_IPHONE
        // define something for iphone  
    #else
        #define TARGET_OS_OSX 1
        // define something for OSX
    #endif
#elif __linux
    // linux
#elif __unix // all unices not caught above
    // Unix
#elif __posix
    // POSIX
#endif
Run Code Online (Sandbox Code Playgroud)


hou*_*anb 6

一个必然的答案:[此站点]上的人花了一些时间为每个OS /编译器对定义宏表。

例如,您可以看到 _WIN32在Windows上未使用Cygwin(POSIX)定义它,而在Windows,Cygwin(非POSIX)和MinGW上使用每个可用的编译器(Clang,GNU,Intel等)进行编译时都未定义。 。

无论如何,我发现这些表非常有用,并认为我会在这里分享。

  • @Lindydancer http://web.archive.org/web/20191012035921/http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system (2认同)