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).
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__
C Preprocessor Mac OS
I think the sourceforge documentation means that you can use either __APPLE__
or __MACH__
.
Detect Windows or Linux in C, C++
It's generally done like this (more or less):
#ifdef _WIN32
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define DIV 1048576
#define WIDTH 7
#endif
#ifdef linux
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#endif
int main(int argc, char *argv[])
{
#ifdef _WIN32
MEMORYSTATUSEX statex;
statex.dwLength = sizeof (statex);
GlobalMemoryStatusEx (&statex);
_tprintf (TEXT("There is %*ld %% of memory in use.\n"),
WIDTH, statex.dwMemoryLoad);
#endif
#ifdef linux
char cmd[30];
int flag = 0;
FILE *fp;
char line[130];
int TotalMem, TotalFree, TotalUsed;
flag=0;
memcpy (cmd,"\0",30);
sprintf(cmd,"free -t -m|grep Total");
fp = popen(cmd, "r");
while ( fgets( line, sizeof line, fp))
{
flag++;
sscanf(line,"%*s %d %d %d",&TotalMem, &TotalUsed, &TotalFree);
}
pclose(fp);
if(flag)
printf("TotalMem:%d -- TotalUsed:%d -- TotalFree:%d\n",TotalMem,TotalUsed,TotalFree);
else
printf("not found\n");
#endif
return 0;
}
This way, only code for linux will be compiled while on a linux platform, and only windows code will be compiled on a windows platform.
How to check if the current operating system is Windows, Linux, or OSX?
The use of #ifdef
uses preprocessor symbols to conditionally compile code depending on which symbols are defined. In your example, the compiler or an #include
file may define WIN32
, which means the code is being compiled in a Win32 environment.
Depending on the compiler and the platform, there may be different predefined symbols that indicate the operating system or processor architecture (among many other possible things) that relate to the current compilation environment.
With gcc
, you can show the predefined symbols using the following command line:
gcc -E -dM - </dev/null
On my machine, one of the defined symbols is:
#define __FreeBSD__ 8
This happens to mean that I'm running FreeBSD version 8.
(The above applies to C and C-family languages such as C++.)
C++ compiling on Windows and Linux: ifdef switch
use:
#ifdef __linux__
//linux code goes here
#elif _WIN32
// windows code goes here
#else
#endif
Related Topics
Copy a File in a Sane, Safe and Efficient Way
Adding External Library into Qt Creator Project
How to Handle Wrong Data Type Input
What Happens If You Static_Cast Invalid Value to Enum Class
What Is the Performance Overhead of Std::Function
C++ Member Initialization List
How to Get Main Window Handle from Process Id
Visual Studio Support For New C/C++ Standards
Is Sizeof(Bool) Defined in the C++ Language Standard
Multithreading Program Stuck in Optimized Mode But Runs Normally in -O0
How to Get and Use the Header File ≪Graphics.H≫ in My C++ Program
C++ Virtual Function from Constructor
What Is a Null-Terminated String
What Are Transparent Comparators