我经常看到__WIN32
,WIN32
或__WIN32__
。我认为这取决于使用的预处理器(来自visual studio或gcc等)。
我现在必须首先检查os,然后检查使用过的编译器吗?我们在这里使用的是G ++ 4.4.x,Visual Studio 2008和Xcode(我假设它是gcc)和ATM我们只使用__WIN32__
,__APPLE__
和__LINUX__
。
答案 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_linux
,hpux
,__hpux
,linux
,__linux
,__linux__
,__MACH__
,{{ 1}},__MINGW32__
,__MINGW64__
,__NetBSD__
,__OpenBSD__
,_POSIX_IPV6
,_POSIX_MAPPED_FILES
,_POSIX_SEMAPHORES
,{{1} },_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__
,{{ 1}},WIN32
,_WIN32
,__WIN32
,__WIN32__
,WIN64
,_WIN64
,__WIN64
,{{1} }。
related article(archive.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__)。
您必须检查每个编译器的文档,以便能够在编译时检测差异。我记得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控制,而不是试图推断编译器将要做什么。