C++ 哪个跨平台预处理器定义?(__WIN32__ 或 __WIN32 或 WIN32)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2989810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Which Cross Platform Preprocessor Defines? (__WIN32__ or __WIN32 or WIN32 )?
提问by math
I often see __WIN32
, WIN32
or __WIN32__
. I assume that this depends on the used preprocessor (either one from visual studio, or gcc etc).
我经常看到__WIN32
,WIN32
或者__WIN32__
。我认为这取决于使用的预处理器(来自 Visual Studio 或 gcc 等)。
Do I now have to check first for os and then for the used compiler? We are using here G++ 4.4.x, Visual Studio 2008 and Xcode (which I assume is a gcc again) and ATM we are using just __WIN32__
, __APPLE__
and __LINUX__
.
我现在是否必须首先检查操作系统然后检查使用的编译器?我们在这里使用 G++ 4.4.x、Visual Studio 2008 和 Xcode(我认为它又是一个 gcc)和 ATM 我们只使用__WIN32__
,__APPLE__
和__LINUX__
.
采纳答案by INS
It depends what you are trying to do. You can check the compiler if your program wants to make use of some specific functions (from the gcc toolchain for example). You can check for operating system ( _WINDOWS, __unix__ ) if you want to use some OS specific functions (regardless of compiler - for example CreateProcess on Windows and fork on unix).
这取决于你想要做什么。如果您的程序想要使用某些特定功能(例如来自 gcc 工具链),您可以检查编译器。如果您想使用某些特定于操作系统的功能(无论编译器如何 - 例如 Windows 上的 CreateProcess 和 unix 上的 fork),您可以检查操作系统( _WINDOWS, __unix__ )。
You must check the documentation of each compiler in order to be able to detect the differences when compiling. I remember that the gnu toolchain(gcc) has some functions in the C library (libc) that are not on other toolchains (like Visual C for example). This way if you want to use those functions out of commodity then you must detect that you are using GCC, so the code you must use would be the following:
您必须检查每个编译器的文档,以便能够在编译时检测差异。我记得 gnu 工具链(gcc)在 C 库(libc)中有一些不在其他工具链(例如 Visual C )上的函数。这样,如果您想在商品之外使用这些功能,那么您必须检测到您正在使用 GCC,因此您必须使用的代码如下:
#ifdef __GNUC__
// do my gcc specific stuff
#else
// ... handle this for other compilers
#endif
回答by Charphacy
This article answers your question:
这篇文章回答了你的问题:
- C/C++ tip: How to detect the operating system type using compiler predefined macros(plus archive.org linkin case it vanishes).
- C/C++ 提示:如何使用编译器预定义宏(加上archive.org 链接,以防它消失)检测操作系统类型。
The article is quite long, and includes tables that are hard to reproduce, but here's the essence:
这篇文章很长,包括难以复制的表格,但这里是本质:
You can detect Unix-style OS with:
您可以通过以下方式检测 Unix 风格的操作系统:
#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
/* UNIX-style OS. ------------------------------------------- */
#endif
Once you know it's Unix, you can find if it's POSIX and the POSIX version with:
一旦你知道它是 Unix,你就可以找到它是否是 POSIX 和 POSIX 版本:
#include <unistd.h>
#if defined(_POSIX_VERSION)
/* POSIX compliant */
#endif
You can check for BSD-derived systems with:
您可以使用以下命令检查 BSD 派生系统:
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#include <sys/param.h>
#if defined(BSD)
/* BSD (DragonFly BSD, FreeBSD, OpenBSD, NetBSD). ----------- */
#endif
#endif
and Linux with:
和 Linux:
#if defined(__linux__)
/* Linux */
#endif
and Apple's operating systems with
和苹果的操作系统
#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
带有 Cygwin 的 Windows
#if defined(__CYGWIN__) && !defined(_WIN32)
/* Cygwin POSIX under Microsoft Windows. */
#endif
And non-POSIX Windows with:
和非 POSIX Windows:
#if defined(_WIN64)
/* Microsoft Windows (64-bit) */
#elif defined(_WIN32)
/* Microsoft Windows (32-bit) */
#endif
The full article lists the following symbols, and shows which systems define them and when: _AIX
, __APPLE__
, __CYGWIN32__
, __CYGWIN__
, __DragonFly__
, __FreeBSD__
, __gnu_linux
, hpux
, __hpux
, linux
, __linux
, __linux__
, __MACH__
, __MINGW32__
, __MINGW64__
, __NetBSD__
, __OpenBSD__
, _POSIX_IPV6
, _POSIX_MAPPED_FILES
, _POSIX_SEMAPHORES
, _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__
, WIN32
, _WIN32
, __WIN32
, __WIN32__
, WIN64
, _WIN64
, __WIN64
, __WIN64__
, WINNT
, __WINNT
, __WINNT__
.
完整的文章列出了以下符号,并显示该系统定义它们,当:_AIX
,__APPLE__
,__CYGWIN32__
,__CYGWIN__
,__DragonFly__
,__FreeBSD__
,__gnu_linux
,hpux
,__hpux
,linux
,__linux
,__linux__
,__MACH__
,__MINGW32__
,__MINGW64__
,__NetBSD__
,__OpenBSD__
,_POSIX_IPV6
,_POSIX_MAPPED_FILES
,_POSIX_SEMAPHORES
,_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__
, WIN32
, _WIN32
, __WIN32
, __WIN32__
, WIN64
, _WIN64
, __WIN64
, __WIN64__
, WINNT
, __WINNT
, __WINNT__
.
A related article(archive.org link) covers detecting compilers and compiler versions. It lists the following symbols: __clang__
, __GNUC__
, __GNUG__
, __HP_aCC
, __HP_cc
, __IBMCPP__
, __IBMC__
, __ICC
, __INTEL_COMPILER
, _MSC_VER
, __PGI
, __SUNPRO_C
, __SUNPRO_CC
for detecting compilers, and __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__
for detecting compiler versions.
一个相关的文章(archive.org链接)覆盖检测编译器和编译器版本。它列出了下列符号:__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__
用于检测编译器版本。
回答by Billy ONeal
Don't see why you have to. You might have to remember to specify the definition manually on your compiler's commandline, but that's all. For the record, Visual Studio's definition is _WIN32
(with one underscore) rather than __WIN32
. If it's not defined then it's not defined, and it won't matter.
不明白为什么必须这样做。您可能必须记住在编译器的命令行上手动指定定义,但仅此而已。作为记录,Visual Studio 的定义是_WIN32
(带一个下划线)而不是__WIN32
. 如果它没有定义,那么它就没有定义,也没有关系。
回答by silmeth
I've rebuild my answer... Damn, editing berserk :P:
我已经重建了我的答案......该死,编辑狂暴:P:
You don't need to use partical one. And probably for MacOSX, Linux and other Unix-likes you don't need to use any at all.
你不需要使用局部的。并且可能对于 MacOSX、Linux 和其他类 Unix 系统,您根本不需要使用任何工具。
Most popular one is (as far as Google tells the truth) is _WIN32
.
最受欢迎的一个是(据谷歌所说)是_WIN32
.
You neverdefine it "by hand" in your source code. It is defined in one of these ways:
as a commandline preprocessor/compiler flag (like g++ -D _WIN32
)
or it is predefined by compiler itself (most of Windows compilers predefine _WIN32
, and sometimes other like WIN32
or _WIN32_
too. -- Then you don't need to worry about defining it at all, compiler does the whole work.
您永远不会在源代码中“手动”定义它。它以以下方式之一定义:
作为命令行预处理器/编译器标志(如g++ -D _WIN32
)
或由编译器本身预定义(大多数 Windows 编译器预定义_WIN32
,有时其他类似WIN32
或_WIN32_
太多。 - 那么你不必担心关于定义它,编译器完成了全部工作。
And my old answer:
我的旧答案:
You don't 'have to' anything. It's just for multi-platform compatibility. Often version of code for all Unix-likes (including Linux, MacOSX, BSD, Solaris...) and other POSIX platform will be completely the same and there must be some changes for Windows. So people write their code generally for Unix-likes and put some Windows-only (eg. DirectX instructions, Windows-like file paths...) parts between #ifdef _WIN32
and #endif
.
你不必“必须”做任何事情。它只是为了多平台兼容性。通常,所有类 Unix(包括 Linux、MacOSX、BSD、Solaris...)和其他 POSIX 平台的代码版本将完全相同,Windows 必须有一些更改。因此,人们通常为类 Unix 编写代码,#ifdef _WIN32
并在#endif
.
If you have some parts eg. X-Window-system only, or MacOS-only, you do similar with something like #ifdef X_WINDOW
or #ifdef MACOS
. Then, you need set a proper preprocessor definition while compiling (with gcc using -D flag, like eg. gcc -D _WIN32
).
如果你有一些零件,例如。仅适用于 X-Window 系统或仅适用于 MacOS,您可以使用类似#ifdef X_WINDOW
或#ifdef MACOS
. 然后,您需要在编译时设置适当的预处理器定义(使用 gcc 使用 -D 标志,例如。gcc -D _WIN32
)。
If you don't write any platform-dependent code, then you don't need to care for such a #ifdef, #else, #endif
blocks. And most of Windows compilers/preprocessors AFAIK have predefined some symbols like _WIN32
(most popular, as far as google tells the truth), WIN32
, _WIN32_
, etc. So compiling it on Windows most probably you don't need to make anything else than just compiling.
如果你不编写任何平台相关的代码,那么你就不需要关心这样的#ifdef, #else, #endif
块。并且大多数 Windows 编译器/预处理器 AFAIK 都预定义了一些符号,如_WIN32
(最流行的,就谷歌所说的而言)WIN32
、_WIN32_
、 等。因此,在 Windows 上编译它很可能除了编译之外您不需要做任何其他事情。
回答by Chris K
Sigh - don't rely on compiler anything - specify which platform you are building for in your Makefile. Simply put, anything beginning with _ is implementation dependent and not portable.
叹气 - 不要依赖编译器任何东西 - 在你的 Makefile 中指定你正在构建的平台。简而言之,任何以 _ 开头的东西都依赖于实现而不是可移植的。
I tried your method once upon a time, on a very large project, and in between bouncing around between Sun-C++ and GCC we just decided to go with Makefile control rather than trying to deduce what the compilers were going to do.
曾几何时,我在一个非常大的项目中尝试过您的方法,在 Sun-C++ 和 GCC 之间跳来跳去,我们只是决定使用 Makefile 控制,而不是试图推断编译器将要做什么。