C++ compiling on Windows and Linux: ifdef switch [duplicate]
Asked Answered
L

7

220

I want to run some c++ code on Linux and Windows. There are some pieces of code that I want to include only for one operating system and not the other. Is there a standard #ifdef that once can use?

Something like:

  #ifdef LINUX_KEY_WORD
    ... // linux code goes here.
  #elif WINDOWS_KEY_WORD
    ... // windows code goes here.
  #else 
  #error "OS not supported!"
  #endif

The question is indeed a duplicate but the answers here are much better, especially the accepted one.

Lichee answered 11/7, 2011 at 12:15 Comment(2)
@MooingDuck: I confirm that I wanted to decided on the target OS not necessarily on the compiler used.Lichee
How to detect reliably Mac OS X, iOS, Linux, Windows in C preprocessor?, Detect Windows or Linux in C, C++Lesalesak
H
275

use:

#ifdef __linux__ 
    //linux code goes here
#elif _WIN32
    // windows code goes here
#else

#endif
Hornswoggle answered 11/7, 2011 at 12:21 Comment(1)
Hi I'm new to C++ programming, could you help me clarify something? In the line #ifdef __linux__, what is the __linux__ part called?Ectropion
P
84

You can do:

#if MACRO0
    //code...
#elif MACRO1
    //code...
#endif

…where the identifier can be:

    __linux__       Defined on Linux
    __sun           Defined on Solaris
    __FreeBSD__     Defined on FreeBSD
    __NetBSD__      Defined on NetBSD
    __OpenBSD__     Defined on OpenBSD
    __APPLE__       Defined on Mac OS X
    __hpux          Defined on HP-UX
    __osf__         Defined on Tru64 UNIX (formerly DEC OSF1)
    __sgi           Defined on Irix
    _AIX            Defined on AIX
    _WIN32          Defined on Windows
Pelf answered 24/3, 2014 at 22:54 Comment(0)
M
48

I know it is not answer but added if someone looking same in Qt

In Qt

https://wiki.qt.io/Get-OS-name-in-Qt

QString Get::osName()
{
#if defined(Q_OS_ANDROID)
    return QLatin1String("android");
#elif defined(Q_OS_BLACKBERRY)
    return QLatin1String("blackberry");
#elif defined(Q_OS_IOS)
    return QLatin1String("ios");
#elif defined(Q_OS_MAC)
    return QLatin1String("osx");
#elif defined(Q_OS_WINCE)
    return QLatin1String("wince");
#elif defined(Q_OS_WIN)
    return QLatin1String("windows");
#elif defined(Q_OS_LINUX)
    return QLatin1String("linux");
#elif defined(Q_OS_UNIX)
    return QLatin1String("unix");
#else
    return QLatin1String("unknown");
#endif
}
Metaxylem answered 26/11, 2014 at 12:15 Comment(0)
L
18

It depends on the used compiler.

For example, Windows' definition can be WIN32 or _WIN32.

And Linux' definition can be UNIX or __unix__ or LINUX or __linux__.

Lurlene answered 11/7, 2011 at 12:21 Comment(2)
There is such a standard. Those toolchains that don't adhere to it, are either buggy, stone-age old, or just bad.Viator
WIN32 is defined inside Windows.h. So, if the header was not included type switch won't work. _WIN32 should be defined by default.Erst
E
13

This response isn't about macro war, but producing error if no matching platform is found.

#ifdef LINUX_KEY_WORD   
... // linux code goes here.  
#elif WINDOWS_KEY_WORD    
... // windows code goes here.  
#else     
#error Platform not supported
#endif

If #error is not supported, you may use static_assert (C++0x) keyword. Or you may implement custom STATIC_ASSERT, or just declare an array of size 0, or have switch that has duplicate cases. In short, produce error at compile time and not at runtime

Exclude answered 11/7, 2011 at 15:41 Comment(2)
#error must be supported (unlike #warning which is an extension). But I agree that it may not necessarily be the best way to fail a build.Zamia
@Thomas: Indeed. Fortunately, if #error is not supported in some non-compliant implementation, the result of the incorrect preprocessor statement is, well --- an error. And if it's not an error either, then the compiler is a REALLY REALLY crappy one and not worth supporting anyways (though I highly doubt such a compiler exists).Goolsby
F
9

It depends on the compiler. If you compile with, say, G++ on Linux and VC++ on Windows, this will do :

#ifdef linux
    ...
#elif _WIN32
    ...
#else
    ...
#endif
Fiddling answered 11/7, 2011 at 12:23 Comment(2)
This will always do. All compilers implement this in the same fashion. Clang on linux mimicks GCC, Clang and GCC on Windows mimicks MSVC.Viator
@rubenvb: All existing compilers, by convenience. This behavior is not standardized and may as well be different for some compilers nobody uses.Fiddling
A
3

No, these defines are compiler dependent. What you can do, use your own set of defines, and set them on the Makefile. See this thread for more info.

Acceptance answered 11/7, 2011 at 12:19 Comment(6)
correct, but not helpfulTurnedon
@Cicada: Compiler dependent has no meaning when all compilers (worth talking about) do the same thing.Viator
yet, there's no standard defining this, and that's what he asked for. I'm updating the answer to point it to an useful reference about thisAcceptance
I'm amused that you suggest makefiles as an alternative to "compiler dependent" defines. More compilers use the same defines than use makefiles.Unabridged
Compilers don't use makefiles, makefiles use compilers.Boiled
Makefiles are a rather unix-like solution usable on windows but not as common. For one thing make isn't installed by default.Vinitavinn

© 2022 - 2024 — McMap. All rights reserved.