How do I check OS with a preprocessor directive?
Solution 1
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__
Solution 2
show GCC defines on Windows:
gcc -dM -E - <NUL:
on Linux:
gcc -dM -E - </dev/null
Predefined macros in MinGW:
WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386
on UNIXes:
unix __unix__ __unix
Solution 3
Based on nadeausoftware and Lambda Fairy's answer.
#include <stdio.h>
/**
* Determination a platform of an operation system
* Fully supported supported only GNU GCC/G++, partially on Clang/LLVM
*/
#if defined(_WIN32)
#define PLATFORM_NAME "windows" // Windows
#elif defined(_WIN64)
#define PLATFORM_NAME "windows" // Windows
#elif defined(__CYGWIN__) && !defined(_WIN32)
#define PLATFORM_NAME "windows" // Windows (Cygwin POSIX under Microsoft Window)
#elif defined(__ANDROID__)
#define PLATFORM_NAME "android" // Android (implies Linux, so it must come first)
#elif defined(__linux__)
#define PLATFORM_NAME "linux" // Debian, Ubuntu, Gentoo, Fedora, openSUSE, RedHat, Centos and other
#elif defined(__unix__) || !defined(__APPLE__) && defined(__MACH__)
#include <sys/param.h>
#if defined(BSD)
#define PLATFORM_NAME "bsd" // FreeBSD, NetBSD, OpenBSD, DragonFly BSD
#endif
#elif defined(__hpux)
#define PLATFORM_NAME "hp-ux" // HP-UX
#elif defined(_AIX)
#define PLATFORM_NAME "aix" // IBM AIX
#elif defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR == 1
#define PLATFORM_NAME "ios" // Apple iOS
#elif TARGET_OS_IPHONE == 1
#define PLATFORM_NAME "ios" // Apple iOS
#elif TARGET_OS_MAC == 1
#define PLATFORM_NAME "osx" // Apple OSX
#endif
#elif defined(__sun) && defined(__SVR4)
#define PLATFORM_NAME "solaris" // Oracle Solaris, Open Indiana
#else
#define PLATFORM_NAME NULL
#endif
// Return a name of platform, if determined, otherwise - an empty string
const char *get_platform_name() {
return (PLATFORM_NAME == NULL) ? "" : PLATFORM_NAME;
}
int main(int argc, char *argv[]) {
puts(get_platform_name());
return 0;
}
Tested with GCC and clang on:
- Debian 8
- Windows (MinGW)
- Windows (Cygwin)
Solution 4
In most cases it is better to check whether a given functionality is present or not. For example: if the function pipe()
exists or not.
Solution 5
#ifdef _WIN32
// do something for windows like include <windows.h>
#elif defined __unix__
// do something for unix like include <unistd.h>
#elif defined __APPLE__
// do something for mac
#endif
Related videos on Youtube
Comments
-
perimosocordiae over 2 years
I need my code to do different things based on the operating system on which it gets compiled. I'm looking for something like this:
#ifdef OSisWindows // do Windows-specific stuff #else // do Unix-specific stuff #endif
Is there a way to do this? Is there a better way to do the same thing?
-
John_West over 8 years@Cory Klein: No-no. this question has been asked years-before
-
ilgaar over 5 yearsThis is about
C
notC++
-
phuclv almost 5 years
-
Akib Azmain over 3 years@CoryKlein No, that question is a duplicate of this question.
-
Cory Klein over 3 years@AkibAzmain You’ve pulled me back into history! Wow what an old question. It was already 5 years old when I first commented 7 years ago! Interestingly, comparative age isn’t definitive criteria for selecting which is the duplicate, but in this case it looks like the other was marked as the duplicate ages ago so it’s a moot question. Have a good day!
-
-
hayalci over 15 yearsis there an easy way to check out if a function is defined ?
-
quinmars over 15 yearsIf you are using autoconfig you can check for functions with AC_CHECK_FUNCS(). AC_CHECK_FUNCS(pipe sqrt) will define HAVE_PIPE and HAVE_SQRT if the functions are available. I don't know how it is with other building tools, but I guess they also support this in a way.
-
Gary Makin almost 10 yearsThis site given does not include iOS, so it fails to be able to distinguish between iOS and OS X.
-
Sebi2020 over 7 yearsgcc: error: unrecognized command line option '--show-defines' gcc: fatal error: no input files compilation terminated.
-
PADYMKO about 7 yearsthe dear @MD XF, please indicate versions of your Windows, MinGW and Cygwin
-
MD XF about 7 yearsWindows 7 Enterprise 6.1.7601. Cygwin 2.7.0-1. I can't find the MinGW version but I downloaded it yesterday.
-
MD XF about 7 yearsYou should probably be made aware though - this program is standard C, so it should work on all compliant systems.
-
MD XF about 7 yearsThat meta post was removed. Funny that a meta post asking about posts removed for reasons of moderation was removed for reasons of moderation.
-
PADYMKO about 7 yearsdear @MD XF, thank you for this information. I added you as contributor on top this answer.
-
Konstantin Burlachenko about 7 years:) Yeah. Absolutely crazy
-
Victor Sergienko about 6 yearsMac OS does not define
__unix__
. Why would you include it in the list? -
katta over 5 yearscpp -dM /dev/null will give you a list of all the gcc predefined macro on your version of installed gcc
-
David Given over 5 yearsCygwin defines the
unix
symbols and doesn't define thewin32
ones, so be careful. OTOH it does define__CYGWIN__
. -
Alcaro over 5 years@MDXF As of C++17, there is __has_include. I don't think it's standardized in C yet, but all major compilers (GCC, Clang, ICC, MSVC) implement it as a vendor-specific extension, even in C mode.
-
phuclv about 5 yearsWindows and Unices are not the only OSes
-
Admin about 4 yearsis
__linux__
same as__ANDROID__
?? -
Ayxan Haqverdili almost 4 yearsWhy is
__linux
not POSIX compliant? -
Ayxan Haqverdili almost 4 yearsThe Windows link is broken
-
Mikhail Zakharov almost 4 years
_AIX
for IBM AIX respectively. -
mklement0 almost 3 yearsThat's handy, but note that
unix
,__unix__
,__unix
don't work on macOS, where only__APPLE__
and__MACH__
are defined. -
Polluks almost 3 years@AyxanHaqverdili not enough underscores
-
mercury about 2 yearsbest answer as it covers cygwin.