ChatGPT解决这个技术问题 Extra ChatGPT

How to identify platform/compiler from preprocessor macros?

I'm writing a cross-platform code, which should compile at linux, windows, Mac OS. On windows, I must support visual studio and mingw.

There are some pieces of platform-specific code, which I should place in #ifdef .. #endif environment. For example, here I placed win32 specific code:

#ifdef WIN32
#include <windows.h>
#endif

But how do I recognize linux and mac OS? What are defines names (or etc.) I should use?

The dupe has a much better accepted answer.
The suggested duplicate is NOT the same question. That question asks only about identifying the operating system, whereas this question also asks about identifying the compiler, which is a very different thing.
@JBentley yet the accepted answer does not even mention compilers, and only talks about OSes (and one "platform"). Not to mention it's a terrible answer relative to what the dupe has to offer.
@rubenvb Then link the other question as a comment. Just because it has a better answer, doesn't make it a duplicate. The question is what determines whether it is a duplicate, not the answers. Closing this one only ensures we'll never get a good quality answer to the compiler-related part of the question, which the so-called "duplicate" cannot ever answer.

C
Community

For Mac OS:

#ifdef __APPLE__

For MingW on Windows:

#ifdef __MINGW32__

For Linux:

#ifdef __linux__

For other Windows compilers, check this thread and this for several other compilers and architectures.


Does __APPLE__ distinguish between OSX and iOS?
__APPLE__ is set for both OS X and iOS. You can #include <TargetConditionals.h> inside #ifdef __APPLE__, which then gives you a TARGET_OS_IPHONE #define.
__MINGW64__ is also available when one uses mingw64
Since __MINGW64__ is referenced, think _MSC_VER for Windows/MSVC is worth a mention (which can also be used to check MSVC Version).
I'm sorry, but this answer is quite incorrect on all accounts and doesn't even answer the question.
J
John Bartholomew

See: http://predef.sourceforge.net/index.php

This project provides a reasonably comprehensive listing of pre-defined #defines for many operating systems, compilers, language and platform standards, and standard libraries.


As of version 1.55, Predef is now included in Boost C++ Libraries.
I know the rules were different when you posted this, but I'm going to have to ask you to edit this post to include more relevant details. Now a days link only answers are strongly discouraged, and I'd like to offer you the chance to save this post before its removal.
As this is the only answer that actually answers the question as stated in the title, and the question is very generic and relevant I strongly advice against removing it. I wouldn't call it a "link only" answer either.
@0x7fffffff: What possible benefit to anyone would there be in duplicating the content of the other answers into this one? If you believe it's really important to have a single definitive answer, then perhaps you should create such an answer yourself (it shouldn't be hard: just glue together the existing answers in some sensible order). Personally I have better things to do with my time, but as a moderator clearly SO is more important to you than to me.
r
rubenvb

Here's what I use:

#ifdef _WIN32 // note the underscore: without it, it's not msdn official!
    // Windows (x64 and x86)
#elif __unix__ // all unices, not all compilers
    // Unix
#elif __linux__
    // linux
#elif __APPLE__
    // Mac OS, not sure if this is covered by __posix__ and/or __unix__ though...
#endif

EDIT: Although the above might work for the basics, remember to verify what macro you want to check for by looking at the Boost.Predef reference pages. Or just use Boost.Predef directly.


use __linux __ instead, linux is not defined when compiling with GCC with GNU extensions disabled (ie -std=c++0x)
@Erbureth Fixed, but one should really use predef.sourceforge.net/index.php as in the highest rated answer.
@rubenvb: indeed. And it got too few votes still, I think :) ... I've turned to their site so many times.
For consistency (perhaps a little pedantic) : the first #if ask if defined, the others test for value. If would be more consistent to do #elif defined(__unix__) , etc, I think.
f
foraidt

If you're writing C++, I can't recommend using the Boost libraries strongly enough.

The latest version (1.55) includes a new Predef library which covers exactly what you're looking for, along with dozens of other platform and architecture recognition macros.

#include <boost/predef.h>

// ...

#if BOOST_OS_WINDOWS

#elif BOOST_OS_LINUX

#elif BOOST_OS_MACOS

#endif

Given that this is boost, this solution will work on different platforms/OSs AND different compilers.
"I can't recommend using the Boost libraries strongly enough...." - I've evaluated Boost three times. It can't pass an evaluation... Most of the bugs report were lucky if they were acknowledged. Lack of acknowledgement points to deeper problems in the engineering process. I believe preprocessor macros and built in C++ Standard Libraries are a safer choice.