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__
.
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).
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
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.
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.
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.
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.