如何使用预处理程序指令检查OS?

per*_*iae 175 c operating-system conditional-compilation c-preprocessor

我需要我的代码根据编译它的操作系统做不同的事情.我正在寻找这样的东西:

#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?有没有更好的方法来做同样的事情?

Lam*_*iry 253

OS网站的预定义宏具有非常完整的检查列表.以下是其中一些内容,以及指向它们的位置的链接:

视窗

_WIN32   32位和
_WIN64   64位仅64位

Unix(Linux,*BSD,Mac OS X)

有关使用此检查的一些缺陷,请参阅此相关问题.

unix
__unix
__unix__

Mac OS X.

__APPLE__
__MACH__

两者都是定义的; 检查要么应该工作.

Linux的

__linux__
linux 已过时(不符合POSIX)
__linux已过时(不符合POSIX标准)

FreeBSD的

__FreeBSD__

  • Mac OS 没有定义`__unix__`。为什么要把它列入清单? (4认同)
  • cpp -dM /dev/null 将为您提供已安装 gcc 版本上所有 gcc 预定义宏的列表 (3认同)
  • 该网站给出的不包括iOS,因此无法区分iOS和OS X。 (2认同)
  • Cygwin 定义了 `unix` 符号而不定义 `win32` 符号,所以要小心。OTOH 它确实定义了`__CYGWIN__`。 (2认同)

小智 66

显示GCC在Windows上定义:

gcc -dM -E - <NUL:
Run Code Online (Sandbox Code Playgroud)

在Linux上:

gcc -dM -E - </dev/null
Run Code Online (Sandbox Code Playgroud)

MinGW中的预定义宏:

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386
Run Code Online (Sandbox Code Playgroud)

在UNIX上:

unix __unix__ __unix
Run Code Online (Sandbox Code Playgroud)


PAD*_*MKO 28

基于nadeausoftwareLambda Fairy的回答.

#include <stdio.h>

/**
 * Determination a platform of an operation system
 * Fully supported supported only GNU GCC/G++, partially on Clang/LLVM
 */

#if defined(_WIN32)
    #define PLATFORM_NAME "windows" // Windows
#elif defined(_WIN64)
    #define PLATFORM_NAME "windows" // Windows
#elif defined(__CYGWIN__) && !defined(_WIN32)
    #define PLATFORM_NAME "windows" // Windows (Cygwin POSIX under Microsoft Window)
#elif defined(__ANDROID__)
    #define PLATFORM_NAME "android" // Android (implies Linux, so it must come first)
#elif defined(__linux__)
    #define PLATFORM_NAME "linux" // Debian, Ubuntu, Gentoo, Fedora, openSUSE, RedHat, Centos and other
#elif defined(__unix__) || !defined(__APPLE__) && defined(__MACH__)
    #include <sys/param.h>
    #if defined(BSD)
        #define PLATFORM_NAME "bsd" // FreeBSD, NetBSD, OpenBSD, DragonFly BSD
    #endif
#elif defined(__hpux)
    #define PLATFORM_NAME "hp-ux" // HP-UX
#elif defined(_AIX)
    #define PLATFORM_NAME "aix" // IBM AIX
#elif defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
    #include <TargetConditionals.h>
    #if TARGET_IPHONE_SIMULATOR == 1
        #define PLATFORM_NAME "ios" // Apple iOS
    #elif TARGET_OS_IPHONE == 1
        #define PLATFORM_NAME "ios" // Apple iOS
    #elif TARGET_OS_MAC == 1
        #define PLATFORM_NAME "osx" // Apple OSX
    #endif
#elif defined(__sun) && defined(__SVR4)
    #define PLATFORM_NAME "solaris" // Oracle Solaris, Open Indiana
#else
    #define PLATFORM_NAME NULL
#endif

// Return a name of platform, if determined, otherwise - an empty string
const char *get_platform_name() {
    return (PLATFORM_NAME == NULL) ? "" : PLATFORM_NAME;
}

int main(int argc, char *argv[]) {
    puts(get_platform_name());
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

通过GCC和clang测试:

  • Debian 8
  • Windows(MinGW)
  • Windows(Cygwin)


qui*_*ars 10

在大多数情况下,最好检查是否存在给定的功能.例如:如果函数pipe()存在与否.

  • 有没有一种简单的方法来检查是否定义了一个函数? (3认同)

ana*_*kod 9

在 MinGW 上,_WIN32定义检查不起作用。这是一个解决方案:

#if defined(_WIN32) || defined(__CYGWIN__)
    // Windows (x86 or x64)
    // ...
#elif defined(__linux__)
    // Linux
    // ...
#elif defined(__APPLE__) && defined(__MACH__)
    // Mac OS
    // ...
#elif defined(unix) || defined(__unix__) || defined(__unix)
    // Unix like OS
    // ...
#else
    #error Unknown environment!
#endif
Run Code Online (Sandbox Code Playgroud)

欲了解更多信息,请查看:https://sourceforge.net/p/predef/wiki/OperatingSystems/


Arj*_*ran 7

#ifdef _WIN32
// do something for windows like include <windows.h>
#elif defined __unix__
// do something for unix like include <unistd.h>
#elif defined __APPLE__
// do something for mac
#endif
Run Code Online (Sandbox Code Playgroud)


Mar*_*ork 5

可以在此处找到MS编译器PreDefined Macros:

http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx

我想你正在寻找:

_WIN32
_WIN64

gcc编译器PreDefined MAcros可以在这里找到:

http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html

我想你正在寻找:

__GNUC__
__GNUC_MINOR__
__GNUC_PATCHLEVEL__

为您预先定义的适当编译器做谷歌.