web-dev-qa-db-fra.com

Quel préprocesseur multiplateforme définit-il? (__WIN32__ ou __WIN32 ou WIN32)?

Je vois souvent __WIN32, WIN32 ou __WIN32__. Je suppose que cela dépend du préprocesseur utilisé (soit de Visual Studio, soit de gcc, etc.).

Dois-je maintenant vérifier d'abord le système d'exploitation, puis le compilateur utilisé? Nous utilisons ici G ++ 4.4.x, Visual Studio 2008 et Xcode (ce qui, je suppose, est à nouveau un gcc) et ATM nous utilisons uniquement __WIN32__, __Apple__ et __LINUX__.

35
math

Cela dépend de ce que vous essayez de faire. Vous pouvez vérifier le compilateur si votre programme souhaite utiliser certaines fonctions spécifiques (de la chaîne d'outils gcc par exemple). Vous pouvez vérifier le système d'exploitation (_WINDOWS, __unix__) si vous souhaitez utiliser certaines fonctions spécifiques au système d'exploitation (quel que soit le compilateur - par exemple CreateProcess sous Windows et fork sous Unix).

Macros pour Visual C

Macros pour gcc

Vous devez vérifier la documentation de chaque compilateur afin de pouvoir détecter les différences lors de la compilation. Je me souviens que la chaîne d’outils gnu (gcc) a certaines fonctions dans la bibliothèque C ( libc ) qui ne figurent pas dans d’autres chaînes d’outils (comme Visual C par exemple). De cette façon, si vous souhaitez utiliser ces fonctions à l’extérieur du produit, vous devez alors détecter que vous utilisez GCC. Le code que vous devez utiliser serait le suivant:

#ifdef __GNUC__
// do my gcc specific stuff
#else
// ... handle this for other compilers
#endif
14
INS

Cet article répond à votre question:

L'article est assez long et inclut des tableaux difficiles à reproduire, mais voici l'essentiel:

Vous pouvez détecter un système d'exploitation de type Unix avec:

#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__Apple__) && defined(__MACH__)))
    /* UNIX-style OS. ------------------------------------------- */

#endif

Une fois que vous savez que c’est Unix, vous pouvez déterminer s’il s’agit de POSIX et de la version POSIX avec:

#include <unistd.h>
#if defined(_POSIX_VERSION)
    /* POSIX compliant */
#endif

Vous pouvez rechercher des systèmes dérivés de BSD avec:

#if defined(__unix__) || (defined(__Apple__) && defined(__MACH__))
#include <sys/param.h>
#if defined(BSD)
    /* BSD (DragonFly BSD, FreeBSD, OpenBSD, NetBSD). ----------- */

#endif
#endif

et Linux avec:

#if defined(__linux__)
    /* Linux  */
#endif

et les systèmes d'exploitation d'Apple avec

#if defined(__Apple__) && defined(__MACH__)
    /* Apple OSX and iOS (Darwin) */
#include <TargetConditionals.h>
#if TARGET_IPHONE_SIMULATOR == 1
    /* iOS in Xcode simulator */
#Elif TARGET_OS_IPHONE == 1
    /* iOS on iPhone, iPad, etc. */    
#Elif TARGET_OS_MAC == 1
    /* OS X */
#endif
#endif

Windows avec Cygwin

#if defined(__CYGWIN__) && !defined(_WIN32)
    /* Cygwin POSIX under Microsoft Windows. */
#endif

Et Windows non-POSIX avec:

#if defined(_WIN64)
    /* Microsoft Windows (64-bit) */
#Elif defined(_WIN32)
    /* Microsoft Windows (32-bit) */
#endif

L'article complet répertorie les symboles suivants et indique quels systèmes les définissent et à quel moment: _AIX, __Apple__, __CYGWIN32__, __CYGWIN__, __DragonFly__, __FreeBSD__, __gnu_linux, hpux, __hpux, linux, __linux, __linux__, __MACH__, __MINGW32__, __MINGW64__, __NetBSD__, __OpenBSD__, _POSIX_IPV6, _POSIX_MAPPED_FILES, _POSIX_SEMAPHORES, _POSIX_THREADS, _POSIX_VERSION, Sun, __Sun, __SunOS, __Sun__, __SVR4, __svr4__, TARGET_IPHONE_SIMULATOR, TARGET_OS_EMBEDDED, TARGET_OS_IPHONE, TARGET_OS_MAC, UNIX, unix , __unix, __unix__, WIN32, _WIN32, __WIN32, __WIN32__, WIN64, _WIN64, __WIN64, __WIN64__, WINNT, __WINNT, __WINNT__.

Un article connexe _ ( lien archive.org ) couvre la détection des compilateurs et de leurs versions. Il répertorie les symboles suivants: __clang__, __GNUC__, __GNUG__, __HP_aCC, __HP_cc, __IBMCPP__, __IBMC__, __ICC, __INTEL_COMPILER, _MSC_VER, __PGI, __SUNPRO_C, __SUNPRO_CC pour détecter les compilateurs, et __clang_major__, __clang_minor__, __clang_patchlevel__, __clang_version__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__, __GNUC__, __GNUG__, __HP_aCC, __HP_cc, __IBMCPP__, __IBMC__, __ICC, __INTEL_COMPILER, __INTEL_COMPILER_BUILD_DATE, _MSC_BUILD, _MSC_FULL_VER, _MSC_VER, __PGIC_MINOR__, __PGIC_PATCHLEVEL__, __PGIC__, __SUNPRO_C, __SUNPRO_CC, __VERSION__, __xlC_ver__, __xlC__, __xlc__ pour détecter les versions du compilateur.

34
Charphacy

Ne vois pas pourquoi tu dois le faire. Vous devrez peut-être vous rappeler de spécifier manuellement la définition sur la ligne de commande de votre compilateur, mais c'est tout. Pour mémoire, la définition de Visual Studio est _WIN32 (avec un trait de soulignement) au lieu de __WIN32. Si ce n'est pas défini, alors ce n'est pas défini, et cela n'aura pas d'importance.

3
Billy ONeal

J'ai reconstruit ma réponse ... Merde, montage berserk: P:

Vous n'avez pas besoin d'utiliser Partical. Et probablement pour MacOSX, Linux et autres Unix-like, vous n'avez pas besoin d'en utiliser du tout.

Le plus populaire est (dans la mesure où Google dit la vérité) est _WIN32.

Vous jamais définissez-le "à la main" dans votre code source. Il est défini de l'une des manières suivantes:
en tant que drapeau de préprocesseur/compilateur de ligne de commande (comme g++ -D _WIN32)
.__ ou il est prédéfini par le compilateur lui-même (la plupart des compilateurs Windows prédéfinissent _WIN32, et parfois d’autres comme WIN32 ou _WIN32_ également. - Alors vous n’aurez plus à vous soucier de le définir, le compilateur fait tout le travail.


Et mon ancienne réponse:

Vous n'avez rien à faire. C'est juste pour la compatibilité multi-plateforme. Souvent, la version du code pour tous les goûts Unix (y compris Linux, MacOSX, BSD, Solaris ...) et les autres plates-formes POSIX sera complètement identique et des modifications devront être apportées pour Windows. Ainsi, les gens écrivent généralement leur code pour les utilisateurs de type Unix et placent certaines parties réservées à Windows (instructions DirectX, chemins de fichiers de type Windows, etc.) entre #ifdef _WIN32 et #endif.

Si vous avez des pièces par exemple. Système X-Window uniquement ou MacOS uniquement, vous procédez de la même manière avec quelque chose comme #ifdef X_WINDOW ou #ifdef MACOS. Ensuite, vous devez définir une définition de préprocesseur appropriée lors de la compilation (avec gcc en utilisant -D, comme par exemple gcc -D _WIN32).

Si vous n'écrivez pas de code dépendant de la plate-forme, vous n'avez pas besoin de vous occuper d'un tel bloc #ifdef, #else, #endif. Et la plupart des compilateurs/pré-processeurs Windows d’AFAIK ont prédéfini des symboles tels que _WIN32 (le plus populaire, autant que google indique la vérité), WIN32, _WIN32_, etc. Ainsi, en le compilant sous Windows, vous n'avez probablement pas besoin de créer autre chose que je viens de compiler.

2
silmeth

Sigh - ne comptez pas sur le compilateur - spécifiez la plate-forme que vous construisez dans votre Makefile. En termes simples, tout ce qui commence par _ dépend de la mise en oeuvre et n'est pas portable. 

J’ai essayé votre méthode jadis, sur un très gros projet, et entre temps de passer de Sun-C++ à GCC, nous avons simplement décidé d’utiliser le contrôle Makefile plutôt que de tenter de déduire ce que les compilateurs allaient faire. 

0
Chris K