324

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?

8
  • 11
    @Cory Klein: No-no. this question has been asked years-before Commented Jan 3, 2016 at 19:53
  • This is about C not C++ Commented Jan 21, 2019 at 17:08
  • How to detect reliably Mac OS X, iOS, Linux, Windows in C preprocessor?, Detect Windows or Linux in C, C++ Commented Jun 2, 2019 at 15:38
  • @CoryKlein No, that question is a duplicate of this question. Commented Oct 10, 2020 at 11:22
  • @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! Commented Oct 10, 2020 at 12:13

20 Answers 20

478

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__

Sign up to request clarification or add additional context in comments.

10 Comments

This site given does not include iOS, so it fails to be able to distinguish between iOS and OS X.
Mac OS does not define __unix__. Why would you include it in the list?
cpp -dM /dev/null will give you a list of all the gcc predefined macro on your version of installed gcc
Cygwin defines the unix symbols and doesn't define the win32 ones, so be careful. OTOH it does define __CYGWIN__.
is __linux__ same as __ANDROID__ ??
|
87

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

3 Comments

Windows and Unices are not the only OSes
That's handy, but note that unix, __unix__, __unix don't work on macOS, where only __APPLE__ and __MACH__ are defined.
gcc on Linux shows error: unrecognized command-line option ‘-q’ with gcc -dM -E - </dev/null
67

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)

5 Comments

the dear @MD XF, please indicate versions of your Windows, MinGW and Cygwin
Windows 7 Enterprise 6.1.7601. Cygwin 2.7.0-1. I can't find the MinGW version but I downloaded it yesterday.
You should probably be made aware though - this program is standard C, so it should work on all compliant systems.
dear @MD XF, thank you for this information. I added you as contributor on top this answer.
This way _WIN64, can never be defined because _WIN32 is defined for both.
10

Microsoft C/C++ compiler (MSVC) Predefined Macros can be found here

I think you are looking for:

  • _WIN32 - Defined as 1 when the compilation target is 32-bit ARM, 64-bit ARM, x86, or x64. Otherwise, undefined
  • _WIN64 - Defined as 1 when the compilation target is 64-bit ARM or x64. Otherwise, undefined.

gcc compiler PreDefined MAcros can be found here

I think you are looking for:

  • __GNUC__
  • __GNUC_MINOR__
  • __GNUC_PATCHLEVEL__

Do a google for your appropriate compilers pre-defined.

Comments

9

On MinGW, the _WIN32 define check isn't working. Here's a solution:

#if defined(_WIN32) || defined(__CYGWIN__)
    // Windows (x86 or x64)
    // ...
#elif defined(__linux__)
    // Linux
    // ...
#elif defined(__APPLE__) && defined(__MACH__)
    // Mac OS
    // ...
#elif defined(unix) || defined(__unix__) || defined(__unix)
    // Unix like OS
    // ...
#else
    #error Unknown environment!
#endif

For more information please look: https://sourceforge.net/p/predef/wiki/OperatingSystems/

1 Comment

best answer as it covers cygwin.
8

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.

3 Comments

is there an easy way to check out if a function is defined ?
If 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.
@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.
8
#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

Comments

4

There is no standard macro that is set according to C standard. Some C compilers will set one on some platforms (e.g. Apple's patched GCC sets a macro to indicate that it is compiling on an Apple system and for the Darwin platform). Your platform and/or your C compiler might set something as well, but there is no general way.

Like hayalci said, it's best to have these macros set in your build process somehow. It is easy to define a macro with most compilers without modifying the code. You can simply pass -D MACRO to GCC, i.e.

gcc -D Windows
gcc -D UNIX

And in your code:

#if defined(Windows)
// do some cool Windows stuff
#elif defined(UNIX)
// do some cool Unix stuff
#else
#    error Unsupported operating system
#endif

Comments

4

You can use Boost.Predef which contains various predefined macros for the target platform including the OS (BOOST_OS_*). Yes boost is often thought as a C++ library, but this one is a preprocessor header that works with C as well!

This library defines a set of compiler, architecture, operating system, library, and other version numbers from the information it can gather of C, C++, Objective C, and Objective C++ predefined macros or those defined in generally available headers. The idea for this library grew out of a proposal to extend the Boost Config library to provide more, and consistent, information than the feature definitions it supports. What follows is an edited version of that brief proposal.

For example

#include <boost/predef.h>
// or just include the necessary header
// #include <boost/predef/os.h>

#if   BOOST_OS_WINDOWS
#elif BOOST_OS_ANDROID
#elif BOOST_OS_LINUX
#elif BOOST_OS_BSD
#elif BOOST_OS_AIX
#elif BOOST_OS_HAIKU
...
#endif

The full list can be found in BOOST_OS operating system macros

Demo on Godbolt

See also How to get platform IDs from boost?

Comments

3

Sorry for the external reference, but I think it is suited to your question:

C/C++ tip: How to detect the operating system type using compiler predefined macros

2 Comments

That meta post was removed. Funny that a meta post asking about posts removed for reasons of moderation was removed for reasons of moderation.
:) Yeah. Absolutely crazy
2

Use #define OSsymbol and #ifdef OSsymbol where OSsymbol is a #define'able symbol identifying your target OS.

Typically you would include a central header file defining the selected OS symbol and use OS-specific include and library directories to compile and build.

You did not specify your development environment, but I'm pretty sure your compiler provides global defines for common platforms and OSes.

See also http://en.wikibooks.org/wiki/C_Programming/Preprocessor

Comments

2

I did not find Haiku definition here. To be complete, Haiku-os definition is simple __HAIKU__

Comments

2

Just to sum it all up, here are a bunch of helpful links.

Comments

1
#ifdef _WIN32
    std::cout << "Running on Windows" << std::endl;
#elif __linux__
    std::cout << "Running on Linux" << std::endl;
#elif __APPLE__
    std::cout << "Running on macOS" << std::endl;
#else
    std::cout << "Unknown operating system" << std::endl;
#endif

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
1

This response also answers the question "how to install software and build tools with pacman in the various MSYS2 terminals."

Detecting your build platform/environment in C and C++ at compile-time in Linux, Windows, GCC, MSYS2, Cygwin, etc.

Defines provided for you

Here are some possible defines which are automatically defined for a given compiler, OS, or platform:

unix
__unix
__unix__
linux
__linux__
__gnu_linux__
_WIN32
_WIN64
__WIN32__
__CYGWIN__
__MINGW32__
__MINGW64__
__MSYS__
__GNUC__

Which ones are defined depends on the compiler, the build environment (ex: the MSYS2 terminal in Windows), and the OS. The results can vary and be somewhat mish-mashed (mixed and overlapping) due to this.

MSYS2 defines you can manually add to your build system

If you are building in MSYS on Windows, see my instructions here for a full GCC or clang setup: Installing & setting up MSYS2 from scratch, including adding all 7 profiles to Windows Terminal...so you can build native Windows applications with gcc on Windows.

Detecting which MSYS2 terminal you are building in can be manually done by inspecting the MSYSTEM environment variable. See my answer here: How to specify in which of the 7 MSYS2 terminals to run a command in Windows from Bash, Command Prompt, & PowerShell.

Possible values for the MSYSTEM environment variable are:

MSYS
MINGW32
MINGW64
UCRT64
CLANG64
CLANG32
CLANGARM64

In your build system, you can then manually define the following C or C++ preprocessor defines, depending on which terminal you are running in:

#define MSYSTEM_MSYS
#define MSYSTEM_MINGW32
#define MSYSTEM_MINGW64
#define MSYSTEM_UCRT64
#define MSYSTEM_CLANG64
#define MSYSTEM_CLANG32
#define MSYSTEM_CLANGARM64

// and if the `MSYSTEM` environment variable is not set:
#define MSYSTEM_NOTSET

This can be done in CMake by adding the following near the top of your main CMakeLists.txt file. See a real example in my eRCaGuy_Linux_Windows_CMake_Sockets_MSYS2 repo:

From CMakeLists.txt:

# Get MSYSTEM environment variable and define it for C and C++ code. 
# - Example `MSYSTEM` values in MSYS2 on Windows are as follows. 
#   See my answers here: 
#     1. https://stackoverflow.com/a/79228659/4561887
#     2. https://stackoverflow.com/a/79201770/4561887
#
#   1. MSYS
#   2. MINGW32
#   3. MINGW64
#   4. UCRT64
#   5. CLANG64
#   6. CLANG32
#   7. CLANGARM64
# - See what `MSYSTEM` is set to by searching 
#   "build/Release/compile_commands.json", for instance, for `-DMSYSTEM` 
#   after building.
set(MSYSTEM_VALUE $ENV{MSYSTEM})
if(MSYSTEM_VALUE)
    add_compile_definitions("MSYSTEM_${MSYSTEM_VALUE}")
else()
    add_compile_definitions("MSYSTEM_NOTSET")
endif()

platform.h detection header file

Include this header file anywhere in your project to print out, at compile time, which of the above defines are defined, including your manual MSYSTEM_* defines:

platform.h:

// platform.h
// By Gabriel Staples
// Apr. 2025
// 
// From: 
// 1. https://stackoverflow.com/a/79228659/4561887
// 2. https://github.com/ElectricRCAircraftGuy/eRCaGuy_Linux_Windows_CMake_Sockets_MSYS2/blob/main/src/platform.h
// 
// Print out some messages at compile time to show which platform we are 
// compiling on.
// - This helps us debug so we can get the correct static asserts on sizes 
//   for the various platforms on which we compile. 
// - See also: 
//   1. https://sourceforge.net/p/predef/wiki/OperatingSystems/
// 
// Note that on my 64-bit x86-64 computer, the sizes of types are the same on 
// `__CYGWIN__` (using the base MSYS2 terminal) on Windows as they are on
// `__gnu_linux__` on Linux. 

#pragma once

#pragma message(">>> Detecting your platform... <<<")

// Automatically defined by your compiler/OS/platform

#ifdef unix
    #pragma message("Compiling on unix")
#endif
#ifdef __unix
    #pragma message("Compiling on __unix")
#endif
#ifdef __unix__
    #pragma message("Compiling on __unix__")
#endif
#ifdef linux
    #pragma message("Compiling on linux")
#endif
#ifdef __linux__
    #pragma message("Compiling on __linux__")
#endif
#ifdef __gnu_linux__
    #pragma message("Compiling on __gnu_linux__")
#endif
#ifdef _WIN32
    #pragma message("Compiling on _WIN32")
#endif
#ifdef _WIN64
    #pragma message("Compiling on _WIN64")
#endif
#ifdef __WIN32__
    #pragma message("Compiling on __WIN32__")
#endif
#ifdef __CYGWIN__
    #pragma message("Compiling on __CYGWIN__")
#endif
#ifdef __MINGW32__
    #pragma message("Compiling on __MINGW32__")
#endif
#ifdef __MINGW64__
    #pragma message("Compiling on __MINGW64__")
#endif
#ifdef __MSYS__
    #pragma message("Compiling on __MSYS__")
#endif
#ifdef __GNUC__
    #pragma message("Compiling on __GNUC__")
#endif

// Custom `MSYSTEM_*` definitions added by me directly via CMakeLists.txt.
// - This is based on the fact that possible `MSYSTEM` environment variable 
//   values set by the MSYS2 terminal environment on Windows include:
//  
//   1. MSYS
//   2. MINGW32
//   3. MINGW64
//   4. UCRT64
//   5. CLANG64
//   6. CLANG32
//   7. CLANGARM64
// 
// - See my answer here: https://stackoverflow.com/a/79201770/4561887

#ifdef MSYSTEM_MSYS
    #pragma message("Compiling on MSYSTEM_MSYS")
#endif
#ifdef MSYSTEM_MINGW32
    #pragma message("Compiling on MSYSTEM_MINGW32")
#endif
#ifdef MSYSTEM_MINGW64
    #pragma message("Compiling on MSYSTEM_MINGW64")
#endif
#ifdef MSYSTEM_UCRT64
    #pragma message("Compiling on MSYSTEM_UCRT64")
#endif
#ifdef MSYSTEM_CLANG64
    #pragma message("Compiling on MSYSTEM_CLANG64")
#endif
#ifdef MSYSTEM_CLANG32
    #pragma message("Compiling on MSYSTEM_CLANG32")
#endif
#ifdef MSYSTEM_CLANGARM64
    #pragma message("Compiling on MSYSTEM_CLANGARM64")
#endif
#ifdef MSYSTEM_NOTSET
    #pragma message("Compiling on MSYSTEM_NOTSET (ie: probably Linux)")
#endif

My test results (building the exact same code on different platforms)

Let's build my Linux/Unix sockets and cmake demo on both Linux and Windows. Here is my project: https://github.com/ElectricRCAircraftGuy/eRCaGuy_Linux_Windows_CMake_Sockets_MSYS2

For each test, whether on Linux or on Windows in one of the 7 MSYS2 terminals, I build the exact same code using the exact same build tools and commands:

make clean
make

If a particular macro from platform.h above is defined, such as __gnu_linux__, it shows up in the build output in a message like this:

note: ‘#pragma message: Compiling on __gnu_linux__’

Here are my full results:

1. Linux Ubuntu 22.04

Compile-time define results after running make clean && make:

unix
__unix
__unix__
linux
__linux__
__gnu_linux__   <== main automatically-defined one I use
__GNUC__
MSYSTEM_NOTSET  <== custom one I defined in CMakeLists.txt

2. Windows 11 in the 7 MSYS2 terminals

Important: for each of the 7 MSYS2 terminals, if you don't run the "build setup" commands to install that terminal's terminal-specific version of gcc, cmake, and make, then it appears to default back to using the base MSYS2 terminal's version of gcc, cmake, and make, assuming you previously installed it with:

pacman -Suy
pacman -S gcc   # Install gcc
pacman -S cmake # Install CMake
pacman -S make  # Install make

However, once you install a given terminal's specific version of those tools into that terminal, such as by running pacman -S mingw-w64-clang-x86_64-clang in the clang64 terminal, then running make in my project will use that version of those tools instead, which in the clang64 terminal will cause CMake to configure and use Clang 20.1.3, for example, instead of the base terminal's GCC GNU 13.3.0.

Here are my MSYS2 Windows build results:

  1. Base msys / msys2 terminal:

    1. Build setup:
      # Update the package database and core system packages; run 
      # repeatedly until no more updates are available
      pacman -Suy  
      
      pacman -S gcc   # Install gcc
      pacman -S cmake # Install CMake
      pacman -S make  # Install make
      
    2. Compile-time define results after running make clean && make:
      unix
      __unix
      __unix__
      __CYGWIN__    <== main automatically-defined one I use
      __MSYS__
      __GNUC__
      MSYSTEM_MSYS  <== custom one I defined in CMakeLists.txt
      
    3. Unix/Linux sockets build in this environment on Windows? Yes
  2. mingw32 terminal:

    1. Build setup:

      pacman -Syu  # run repeatedly until there are no more updates
      pacman -S mingw-w64-i686-gcc    # Install gcc
      pacman -S mingw-w64-i686-cmake  # Install CMake
      pacman -S mingw-w64-i686-make   # Install make
      
    2. Compile-time define results after running make clean && make:

      _WIN32
      __WIN32__
      __MINGW32__      <== main automatically-defined one I use
      __GNUC__
      MSYSTEM_MINGW32  <== custom one I defined in CMakeLists.txt
      
    3. Unix/Linux sockets build in this environment on Windows? No!

      Error:

      eRCaGuy_Linux_Windows_CMake_Sockets_MSYS2/src/main_server.cpp:83:10: fatal error: arpa/inet.h: No such file or directory
      83 | #include <arpa/inet.h>
          |          ^~~~~~~~~~~~~
      

      I commented out almost all of the file in main_client.cpp just to get it to build far enough for me to see the compile-time macro define results above.

      Here is what I left in main_client.cpp to get it to compile:

      #include "platform.h"
      
      int main()
      {
          return 0;
      }
      
  3. mingw64 terminal:

    1. Build setup:
      pacman -Syu  # run repeatedly until there are no more updates
      pacman -S mingw-w64-x86_64-gcc      # Install gcc
      pacman -S mingw-w64-x86_64-cmake    # Install CMake
      pacman -S mingw-w64-x86_64-make     # Install make
      
    2. Compile-time define results after running make clean && make:
      _WIN32
      _WIN64
      __WIN32__
      __MINGW32__
      __MINGW64__      <== main automatically-defined one I use
      __GNUC__
      MSYSTEM_MINGW64  <== custom one I defined in CMakeLists.txt
      
    3. Unix/Linux sockets build in this environment on Windows? No! Same error as mingw32 above.
  4. ucrt64 terminal:

    1. Build setup:
      pacman -Syu  # run repeatedly until there are no more updates
      pacman -S mingw-w64-ucrt-x86_64-gcc     # Install gcc
      pacman -S mingw-w64-ucrt-x86_64-cmake   # Install CMake
      pacman -S mingw-w64-ucrt-x86_64-make    # Install make
      
    2. Compile-time define results after running make clean && make (same as mingw64, except for my custom definition):
      _WIN32
      _WIN64
      __WIN32__
      __MINGW32__
      __MINGW64__     <== main automatically-defined one I use
      __GNUC__
      MSYSTEM_UCRT64  <== custom one I defined in CMakeLists.txt
      
    3. Unix/Linux sockets build in this environment on Windows? No! Same error as mingw32 above.
  5. clang64 terminal:

    1. Build setup:
      pacman -Syu  # run repeatedly until there are no more updates
      pacman -S mingw-w64-clang-x86_64-clang  # Install clang
      pacman -S mingw-w64-clang-x86_64-cmake  # Install CMake
      pacman -S mingw-w64-clang-x86_64-make   # Install make
      
    2. Compile-time define results after running make clean && make (same as mingw64, except for my custom definition):
      _WIN32
      _WIN64
      __WIN32__
      __MINGW32__
      __MINGW64__      <== main automatically-defined one I use
      __GNUC__
      MSYSTEM_CLANG64  <== custom one I defined in CMakeLists.txt
      
    3. Unix/Linux sockets build in this environment on Windows? No! Same error as mingw32 above. Except the colored output is prettier because clang generally does a better job at beautification and compile-time messages than gcc does.
  6. clang32 terminal: [deprecated; no longer opens after running pacman -Syu repeatedly, to completion]

  7. clangarm64 terminal:

    1. Build setup:

      pacman -Syu  # run repeatedly until there are no more updates
      pacman -S mingw-w64-clang-aarch64-clang  # Install clang
      pacman -S mingw-w64-clang-aarch64-cmake  # Install CMake
      pacman -S mingw-w64-clang-aarch64-make   # Install make
      
    2. Compile-time define results after running make clean && make:

      NA. Cannot run cmake, probably because I'm on an x86-64 computer and the clangarm64 terminal is for ARM64-based CPUs.

      $ make clean && make
      rm -rf build/
      ./cmake_configure_and_build.sh "debug"
      ===================================================================
      Configuring and building debug...
      ./cmake_configure_and_build.sh: line 14: /clangarm64/bin/cmake: cannot execute binary file: Exec format error
      ./cmake_configure_and_build.sh: line 15: /clangarm64/bin/cmake: cannot execute binary file: Exec format error
      make: *** [Makefile:16: debug] Error 126
      

References

  1. The main answer
  2. The main answer's primary reference: Pre-defined Compiler Macros Wiki: https://sourceforge.net/p/predef/wiki/OperatingSystems/
  3. How can I detect g++ and MinGW in C++ preprocessor?
  4. My answer: Installing & setting up MSYS2 from scratch, including adding all 7 profiles to Windows Terminal...so you can build native Windows applications with gcc on Windows.
  5. My repo: full demo of building and running Unix sockets in the MSYS terminl on Windows: https://github.com/ElectricRCAircraftGuy/eRCaGuy_Linux_Windows_CMake_Sockets_MSYS2
  6. My answer: How to specify in which of the 7 MSYS2 terminals to run a command in Windows from Bash, Command Prompt, & PowerShell

Comments

0

Some compilers will generate #defines that can help you with this. Read the compiler documentation to determine what they are. MSVC defines one that's __WIN32__, GCC has some you can see with touch foo.h; gcc -dM foo.h

2 Comments

gcc: error: unrecognized command line option '--show-defines' gcc: fatal error: no input files compilation terminated.
The MSVC link above currently redirects to learn.microsoft.com/en-us/cpp/preprocessor/… - and that lists a _WIN32 macro but not __WIN32__. I've also looked at an archived version - web.archive.org/web/20100422132954/http://msdn.microsoft.com:80/… - and that also lists _WIN32 but not __WIN32__.
0

You can use pre-processor directives as warning or error to check at compile time you don't need to run this program at all just simply compile it .

#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
    #error Windows_OS
#elif defined(__linux__)
    #error Linux_OS
#elif defined(__APPLE__) && defined(__MACH__)
    #error Mach_OS
#elif defined(unix) || defined(__unix__) || defined(__unix)
    #error Unix_OS
#else
    #error Unknown_OS
#endif

#include <stdio.h>
int main(void)
{
    return 0;
}

1 Comment

I don't know why this was down-voted. Great idea here, not needing to run it just for checking prep's. I suppose you need to enable all warnings in the compiler. For gcc, use -Wall. #warning may be even better, to avoid stopping the compile, but only seem to work in GCC and not MSVC.
0

Old question but wanted to share my personal usage:

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
#   define TL_PLATFORM_WINDOWS 1
#   ifndef _WIN64
#       error "64-bit is required on Windows!"
#   endif
#elif defined(__linux__) || defined(__gnu_linux__)
#   define TL_PLATFORM_LINUX 1
#   if defined(__ANDROID__)
#       define TL_PLATFORM_ANDROID 1
#   endif
#elif defined(__unix__)
#   define TL_PLATFORM_UNIX 1
#elif defined(_POSIX_VERSION)
#   define TL_PLATFORM_POSIX 1
#elif __APPLE__
#   define TL_PLATFORM_APPLE 1
#   include <TargetConditionals.h>
#   if TARGET_IPHONE_SIMULATOR
#       define TL_PLATFORM_IOS 1
#       define TL_PLATFORM_IOS_SIMULATOR 1
#   elif TARGET_OS_IPHONE
#       define TL_PLATFORM_IOS 1
#   elif TARGET_OS_MAC
#   else
#       error "Unknown Apple platform"
#   endif
#else
#   error "Unknown platform!"
#endif

On my C projects thats my standard platform detection macro.

Comments

0

in this C program you can detect Operating System :

#include <stdio.h>

int main() {
    #ifdef __WIN32__
        // windows ...
    #elif __linux__
        //linux ...
    #else
        printf("Not support");
    #endif
        return 0;
}

check other os :

__WIN64__ -> (only windows 64-bit)
__APPLE__
TARGET_OS_EMBEDDED
TARGET_IPHONE_SIMULATOR
TARGET_OS_IPHONE
TARGET_OS_MAC
__ANDROID__
__unix__
_POSIX_VERSION
__sun -> (Solaris OS)
__hpux -> (HP UX OS)
__BSD__
__DragonFly__ -> (DragonFly BSD OS)
__FreeBSD__
__NetBSD__
__OpenBSD__

Comments

-2

I wrote an small library to get the operating system you are on, it can be installed using clib (The C package manager), so it is really simple to use it as a dependency for your projects.

Install

$ clib install abranhe/os.c

Usage

#include <stdio.h>
#include "os.h"

int main()
{
    printf("%s\n", operating_system());
    // macOS
    return 0;
}

It returns a string (char*) with the name of the operating system you are using, for further information about this project check it out the documentation on Github.

1 Comment

This doesn't answer the question asked.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.