Are there any macros to determine if my code is being compiled to Windows?
[Edit: I assume you want to use compile-time macros to determine which environment you're on. Maybe you want to determine if you're running on Wine under Linux or something instead of Windows, but in general, your compiler targets a specific environment, and that is either Windows (DOS) or it isn't, but it's rarely (never?) both.]
Some compilers offer macros to indicate a Windows build environment. But these will vary from compiler to compiler, and even on the same compiler on Windows if the target environment is not exclusively windows. Usually it's __WIN32__
, but not always.
#if defined (__WIN32__)
// Windows stuff
#endif
Sometimes it can be _WIN32
, __CYGWIN32__
, or possibly just the compiler indicator (_MSC_VER
).
If you know the environment you'll be building in (from the makefile) then you can usually pass in the #define
on the command line, like "g++ -D __WIN32__ yourfile.c
".
A little more info here
C++ compile time macros to detect windows os
The OS that it's getting compiled on is not all that important; what matters more is the OS that the code is running on, which you obviously cannot detect at compile time. But if you want your code to run on older versions of Windows, you can set WINVER
and _WIN32_WINNT
to certain values, which will cause newer functions not to be available etc. (just search the Windows header files for where those macros get tested to get an idea).
To test for functionality at runtime, use GetProcAddress
(and possibly also LoadLibrary
, if it's in a newer DLL) to test if the function is available. If it is, call it, if not, don't.
See also the predefined macros used by the Visual Studio compiler if you want to detect the compiler version etc.
How to Detect if I'm Compiling Code with a particular Visual Studio version?
_MSC_VER
and possibly _MSC_FULL_VER
is what you need. You can also examine visualc.hpp in any recent boost install for some usage examples.
Some values for the more recent versions of the compiler are:
MSVC++ 14.24 _MSC_VER == 1924 (Visual Studio 2019 version 16.4)
MSVC++ 14.23 _MSC_VER == 1923 (Visual Studio 2019 version 16.3)
MSVC++ 14.22 _MSC_VER == 1922 (Visual Studio 2019 version 16.2)
MSVC++ 14.21 _MSC_VER == 1921 (Visual Studio 2019 version 16.1)
MSVC++ 14.2 _MSC_VER == 1920 (Visual Studio 2019 version 16.0)
MSVC++ 14.16 _MSC_VER == 1916 (Visual Studio 2017 version 15.9)
MSVC++ 14.15 _MSC_VER == 1915 (Visual Studio 2017 version 15.8)
MSVC++ 14.14 _MSC_VER == 1914 (Visual Studio 2017 version 15.7)
MSVC++ 14.13 _MSC_VER == 1913 (Visual Studio 2017 version 15.6)
MSVC++ 14.12 _MSC_VER == 1912 (Visual Studio 2017 version 15.5)
MSVC++ 14.11 _MSC_VER == 1911 (Visual Studio 2017 version 15.3)
MSVC++ 14.1 _MSC_VER == 1910 (Visual Studio 2017 version 15.0)
MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015 version 14.0)
MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013 version 12.0)
MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012 version 11.0)
MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010 version 10.0)
MSVC++ 9.0 _MSC_FULL_VER == 150030729 (Visual Studio 2008, SP1)
MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008 version 9.0)
MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005 version 8.0)
MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio .NET 2003 version 7.1)
MSVC++ 7.0 _MSC_VER == 1300 (Visual Studio .NET 2002 version 7.0)
MSVC++ 6.0 _MSC_VER == 1200 (Visual Studio 6.0 version 6.0)
MSVC++ 5.0 _MSC_VER == 1100 (Visual Studio 97 version 5.0)
The version number above of course refers to the major version of your Visual studio you see in the about box, not to the year in the name. A thorough list can be found here. Starting recently, Visual Studio will start updating its ranges monotonically, meaning you should check ranges, rather than exact compiler values.
cl.exe /?
will give a hint of the used version, e.g.:
c:\program files (x86)\microsoft visual studio 11.0\vc\bin>cl /?
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.50727.1 for x86
.....
How do I check OS with a preprocessor directive?
The Predefined Macros for OS site has a very complete list of checks. Here are a few of them, with links to where they're found:
Windows
_WIN32
Both 32 bit and 64 bit_WIN64
64 bit only__CYGWIN__
Unix (Linux, *BSD, but not Mac OS X)
See this related question on some of the pitfalls of using this check.
unix
__unix
__unix__
Mac OS X
__APPLE__
Also used for classic__MACH__
Both are defined; checking for either should work.
Linux
__linux__
linux
Obsolete (not POSIX compliant)__linux
Obsolete (not POSIX compliant)
FreeBSD
__FreeBSD__
Android
__ANDROID__
How to identify platform/compiler from preprocessor macros?
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.
Is there any way I can tell if my code is being compiled with cl.exe?
If you want to make decisions on the cl.exe
version, use _MSC_BUILD
.
However, first check for _MSC_VER
, because _MSC_BUILD
was not available in VS 2005.
C++ compiling on Windows and Linux: ifdef switch
use:
#ifdef __linux__
//linux code goes here
#elif _WIN32
// windows code goes here
#else
#endif
How to detect reliably Mac OS X, iOS, Linux, Windows in C preprocessor?
There are predefined macros that are used by most compilers, you can find the list here. GCC compiler predefined macros can be found here.
Here is an example for gcc:
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
//define something for Windows (32-bit and 64-bit, this part is common)
#ifdef _WIN64
//define something for Windows (64-bit only)
#else
//define something for Windows (32-bit only)
#endif
#elif __APPLE__
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR
// iOS, tvOS, or watchOS Simulator
#elif TARGET_OS_MACCATALYST
// Mac's Catalyst (ports iOS API into Mac, like UIKit).
#elif TARGET_OS_IPHONE
// iOS, tvOS, or watchOS device
#elif TARGET_OS_MAC
// Other kinds of Apple platforms
#else
# error "Unknown Apple platform"
#endif
#elif __ANDROID__
// Below __linux__ check should be enough to handle Android,
// but something may be unique to Android.
#elif __linux__
// linux
#elif __unix__ // all unices not caught above
// Unix
#elif defined(_POSIX_VERSION)
// POSIX
#else
# error "Unknown compiler"
#endif
The defined macros depend on the compiler that you are going to use.
The _WIN64
#ifdef
can be nested into the _WIN32
#ifdef
because _WIN32
is even defined when targeting the Windows x64 version. This prevents code duplication if some header includes are common to both
(also WIN32
without underscore allows IDE to highlight the right partition of code).
Performing a conditional function based on windows OS
You can use GetVersionEx()
. Read GetVersionEx function and OSVERSIONINFOEX structure for details on how to interpret the data.
Conditional compilation in C++ based on operating system
My gcc (4.3.3) defines the following Linux-related predefined macros:
$ gcc -dM -E - < /dev/null | grep -i linux
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
#define linux 1
Under VC++ (and many other Win32 compilers) there are also a couple of predefined macros identifying the platform, most notably _WIN32. Further details: http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx
Related Topics
Why Does This Code with '1234' Compile in C++
How to Use Std::Filesystem on Gcc 8
Variadic Template in VS 2012 (Visual C++ November 2012 Ctp)
How to Have Two Functions That Call Each Other C++
Static Constexpr Odr-Used or Not
At What Point Does Dereferencing the Null Pointer Become Undefined Behavior
C++ Int with Preceding 0 Changes Entire Value
Reset Cuda Context After Exception
Heap Corruption While Using Createwindowexw
Variadic Deduction Guide Not Taken by G++, Taken by Clang++ - Who Is Correct
Can Compiler Generate Std::Move for a Last Use of Lvalue Automatically
How to Get the Path of a Windows "Special Folder" for a Specific User
What's the Right Way to Use the Rand() Function in C++
C++ Function Callbacks: Cannot Convert from a Member Function to a Function Signature