Comment puis-je vérifier L'OS avec une directive préprocesseur?

j'ai besoin de mon code pour faire des choses différentes basées sur le système d'exploitation sur lequel il est compilé. Je cherche quelque chose comme ceci:

#ifdef OSisWindows
// do Windows-specific stuff
#else
// do Unix-specific stuff
#endif

y a-t-il un moyen de le faire? Est-il une meilleure façon de faire la même chose?

134
demandé sur perimosocordiae 2008-09-27 03:44:00

13 réponses

le site Macros prédéfinies pour OS a une liste très complète de vérifications. En voici quelques-uns, avec des liens vers l'endroit où ils se trouvent:

Windows

_WIN32 les deux 32 bits et 64 bits

_WIN64 64 bit seulement

Unix (Linux, * BSD, Mac OS X)

voir ce question connexe sur certains des pièges de l'utilisation de cette vérification.

unix

__unix

__unix__

Mac OS X

__APPLE__

__MACH__

les deux sont définis; vérifier l'un ou l'autre devrait fonctionner.

Linux

__linux__

linux obsolète (non conforme à POSIX))

__linux Obsolete (not POSIX compliant)

FreeBSD

__FreeBSD__

198
répondu Lambda Fairy 2018-01-11 03:37:29

afficher GCC définit sur Windows:

gcc -dM -E - <NUL:

sur Linux:

gcc -dM -E - </dev/null

macros prédéfinies dans MinGW:

WIN32 _WIN32 __WIN32 __WIN32__ __MINGW32__ WINNT __WINNT __WINNT__ _X86_ i386 __i386

sur UNIXes:

unix __unix__ __unix
60
répondu qwer 2017-03-09 03:45:08

Basé sur nadeausoftware et Lambda de la Fée réponse .

#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
char *
get_platform_name() {
    return (PLATFORM_NAME == NULL) ? "" : PLATFORM_NAME;
}

int main(int argc, char *argv[]) {
    puts(get_platform_name());
    return 0;
}

Testé avec GCC et clang on:

  • Debian 8
  • Windows (MinGW)
  • Windows (Cygwin)
15
répondu Seti Volkylany 2018-03-21 09:06:50

Dans la plupart des cas, il est préférable de vérifier si une fonctionnalité est présente ou non. Par exemple: si la fonction pipe() existe ou pas.

10
répondu quinmars 2017-03-09 03:45:42
#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
7
répondu Arjun Sreedharan 2017-03-09 03:46:35

ms compiler Macros prédéfinies peuvent être trouvées ici:

http://msdn.microsoft.com/en-us/library/b0084kay (VS.80).aspx

je pense que vous cherchez:

_WIN32

_WIN64

gcc compilateur MAcros prédéfinies peuvent être trouvées ici:

http://gcc.gnu.org/onlinedocs/cpp/Predefined-Macros.html

je pense que vous cherchez:

_ _ GNUC_ _

__ GNUC _ MINOR _ _

__GNUC _ PATCHLEVEL__

faites un google pour vos compilateurs appropriés prédéfinis.

5
répondu Martin York 2017-03-09 16:30:29

il n'y a pas de macro standard définie selon la norme C. Certains compilateurs C vont en configurer un sur certaines plateformes (par exemple, le GCC patché D'Apple définit une macro pour indiquer qu'il compile sur un système Apple et pour la plateforme Darwin). Votre plate-forme et/ou votre compilateur C peut définir quelque chose aussi bien, mais il n'y a pas de manière générale.

comme hayalci l'a dit, il est préférable d'avoir ces macros réglées dans votre processus de construction d'une façon ou d'une autre. Il est facile de définir une macro compilateurs sans modifier le code. Vous pouvez simplement passer -D MACRO à GCC, i.e.

gcc -D Windows
gcc -D UNIX

et dans votre code:

#if defined(Windows)
// do some cool Windows stuff
#elif defined(UNIX)
// do some cool Unix stuff
#else
#    error Unsupported operating system
#endif
3
répondu Mecki 2017-03-09 15:24:35

sur MinGW, le _WIN32 define check ne fonctionne pas. Voici une 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

pour de plus amples informations, veuillez consulter: https://sourceforge.net/p/predef/wiki/OperatingSystems /

3
répondu anakod 2017-03-21 21:16:13

utiliser #define OSsymbol et #ifdef OSsymbol où OSsymbol est un #define 'able symbole identifiant votre OS cible.

typiquement, vous incluez un fichier d'en-tête central définissant le symbole OS sélectionné et utilisez les répertoires include et library spécifiques à OS pour compiler et construire.

vous n'avez pas spécifié votre environnement de développement, mais je suis sûr que votre compilateur fournit des définitions globales pour les plates-formes communes et les os.

Voir aussi http://en.wikibooks.org/wiki/C_Programming/Preprocessor

2
répondu devio 2017-03-09 03:50:56

désolé pour la référence externe, mais je pense qu'elle convient à votre question:

C/C++ astuce: Comment détecter le type de système d'exploitation à l'aide de compilateur macros prédéfinies

2
répondu bruziuz 2017-03-20 19:33:16

certains compilateurs vont générer des #definitions qui peuvent vous aider avec cela. Lisez la documentation du compilateur pour déterminer ce qu'ils sont. MSVC définit un qui est __WIN32__ , GCC a certains que vous pouvez voir avec touch foo.h; gcc -dM foo.h

1
répondu davenpcj 2017-03-09 03:51:24

vous pouvez utiliser directives pré-processeur comme avertissement ou erreur pour vérifier au moment de la compilation vous n'avez pas besoin de exécuter ce programme tout simplement compiler il .

#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;
}
0
répondu HaSeeB MiR 2018-01-10 21:44:44