哪个跨平台预处理器定义了? (__WIN32__ 或 __WIN32 或 WIN32 )?
我经常看到 __WIN32
、WIN32
或 __WIN32__
。我认为这取决于所使用的预处理器(来自 Visual Studio 的预处理器或 gcc 等)。
我现在是否必须首先检查操作系统,然后检查所使用的编译器?我们在这里使用 G++ 4.4.x、Visual Studio 2008 和 Xcode(我假设它又是 gcc),而 ATM 我们只使用 __WIN32__
、__APPLE__
和 __LINUX__
。
I often see __WIN32
, WIN32
or __WIN32__
. I assume that this depends on the used preprocessor (either one from visual studio, or gcc etc).
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__
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
本文回答了您的问题:
这篇文章很长,并且包含难以重现的表格,但要点如下:
您可以通过以下方式检测 Unix 风格的操作系统:
一旦您知道它是 Unix,您就可以通过以下方式查找它是否是 POSIX 以及 POSIX 版本:
您可以检查对于 BSD 派生系统:
和 Linux:
以及 Apple 操作系统,带有
Cygwin 的 Windows
和非 POSIX Windows:
完整的文章列出了以下符号,并显示了哪些系统定义它们以及何时定义它们:
_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
、__SunOS
、__sun__
、__SVR4
、__svr4__
、TARGET_IPHONE_SIMULATOR< /code>,
、TARGET_OS_EMBEDDED
,TARGET_OS_IPHONE
,TARGET_OS_MAC
,UNIX
,unix
, <代码>__unix__unix__
、WIN32
、_WIN32
、__WIN32
、__WIN32__
代码>、<代码>WIN64、<代码>_WIN64、<代码>__WIN64、<代码>__WIN64__、<代码>WINNT、<代码>__WINNT,__WINNT__
。相关文章 (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__< /code>,
、__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__
用于检测编译器版本。This article answers your question:
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:
Once you know it's Unix, you can find if it's POSIX and the POSIX version with:
You can check for BSD-derived systems with:
and Linux with:
and Apple's operating systems with
Windows with Cygwin
And non-POSIX Windows with:
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__
.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.这取决于你想做什么。如果您的程序想要使用某些特定函数(例如来自 gcc 工具链),您可以检查编译器。如果您想使用某些操作系统特定的函数(无论编译器如何 - 例如
CreateProcess
),您可以检查操作系统(_WINDOWS
,__unix__
) Windows 和 unix 上的fork
)。Visual C 宏
gcc 宏
必须检查各个编译器的文档,以便在编译时能够发现差异。我记得gnu工具链(gcc)在C库中有一些函数(libc)不在其他工具链上(例如 Visual C)。这样,如果您想使用这些非商品功能,那么您必须检测到您正在使用 GCC,因此您必须使用的代码如下:
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 exampleCreateProcess
on Windows andfork
on unix).Macros for Visual C
Macros for gcc
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:
不明白为什么你必须这样做。您可能必须记住在编译器的命令行上手动指定定义,但仅此而已。根据记录,Visual Studio 的定义为
_WIN32< /code>
(带一个下划线)而不是
__WIN32
。如果它没有定义,那么它就没有定义,也没关系。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.我已经重建了我的答案...该死,编辑狂暴:P:
你不需要使用部分答案。也许对于 MacOSX、Linux 和其他类 Unix 系统,你根本不需要使用任何东西。
最流行的一个是(据 Google 所说)
_WIN32
。您永远不会在源代码中“手动”定义它。它通过以下方式之一定义:
作为命令行预处理器/编译器标志(如
g++ -D _WIN32
)或者它是由编译器本身预定义的(大多数 Windows 编译器预定义了
_WIN32
,有时也预定义了WIN32
或_WIN32_
。 -- 那么你就不需要根本不需要担心定义它,编译器会完成全部工作。我的旧答案是:
你不需要“必须”做任何事情,这只是为了所有类 Unix 的代码版本。包括 Linux、MacOSX、BSD、Solaris...)和其他 POSIX 平台将完全相同,并且对于 Windows 必须有一些更改,因此人们通常为类 Unix 编写代码并放置一些仅限 Windows 的代码(例如 DirectX)。指令、类似 Windows 的文件路径...)
#ifdef _WIN32
和#endif
之间的部分,如果您只有 X-Window 系统或 MacOS。 -only,您可以对
#ifdef X_WINDOW
或#ifdef MACOS
进行类似的操作,然后,您需要在编译时设置正确的预处理器定义(使用 gcc 使用 -D 标志,例如gcc -D _WIN32
)。如果您不编写任何与平台相关的代码,那么您不需要关心这样的
#ifdef、#else、#endif
块。大多数 Windows 编译器/预处理器 AFAIK 都预定义了一些符号,例如_WIN32
(最流行,据 google 报道)、WIN32
、_WIN32_
等。因此,在 Windows 上编译它很可能除了编译之外不需要做任何其他事情。I've rebuild my answer... Damn, editing berserk :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.
Most popular one is (as far as Google tells the truth) is
_WIN32
.You never define 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 likeWIN32
or_WIN32_
too. -- Then you don't need to worry about defining it at all, compiler does the whole work.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
.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
).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.叹息 - 不要依赖任何编译器 - 在 Makefile 中指定你正在构建的平台。简而言之,任何以 _ 开头的内容都是依赖于实现的并且不可移植。
我曾经在一个非常大的项目中尝试过你的方法,在 Sun-C++ 和 GCC 之间来回切换,我们只是决定使用 Makefile 控制,而不是试图推断编译器将要做什么。
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.
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.