哪个跨平台预处理器定义了? (__WIN32__ 或 __WIN32 或 WIN32 )?

发布于 2024-09-04 04:24:33 字数 303 浏览 3 评论 0原文

我经常看到 __WIN32WIN32__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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

对你再特殊 2024-09-11 04:24:33

本文回答了您的问题:

这篇文章很长,并且包含难以重现的表格,但要点如下:

您可以通过以下方式检测 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:

#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

Cygwin 的 Windows

#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_linuxhpux__hpuxlinux__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:

#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:

#include <unistd.h>
#if defined(_POSIX_VERSION)
    /* POSIX compliant */
#endif

You can check for BSD-derived systems with:

#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:

#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

#if defined(__CYGWIN__) && !defined(_WIN32)
    /* Cygwin POSIX under Microsoft Windows. */
#endif

And non-POSIX Windows with:

#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__.

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.

苏佲洛 2024-09-11 04:24:33

这取决于你想做什么。如果您的程序想要使用某些特定函数(例如来自 gcc 工具链),您可以检查编译器。如果您想使用某些操作系统特定的函数(无论编译器如何 - 例如 CreateProcess),您可以检查操作系统(_WINDOWS__unix__) Windows 和 unix 上的 fork)。

Visual C 宏

gcc 宏

必须检查各个编译器的文档,以便在编译时能够发现差异。我记得gnu工具链(gcc)在C库中有一些函数(libc)不在其他工具链上(例如 Visual C)。这样,如果您想使用这些非商品功能,那么您必须检测到您正在使用 GCC,因此您必须使用的代码如下:

#ifdef __GNUC__
// do my gcc specific stuff
#else
// ... handle this for other compilers
#endif

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).

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:

#ifdef __GNUC__
// do my gcc specific stuff
#else
// ... handle this for other compilers
#endif
冷夜 2024-09-11 04:24:33

不明白为什么你必须这样做。您可能必须记住在编译器的命令行上手动指定定义,但仅此而已。根据记录,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.

那伤。 2024-09-11 04:24:33

我已经重建了我的答案...该死,编辑狂暴: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 like WIN32 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.

面如桃花 2024-09-11 04:24:33

叹息 - 不要依赖任何编译器 - 在 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文