web-dev-qa-db-fra.com

Détection de l'architecture du processeur au moment de la compilation

Quelle est la manière la plus fiable de découvrir l'architecture CPU lors de la compilation de code C ou C++? Pour autant que je sache, différents compilateurs ont leur propre ensemble de définitions de préprocesseur non standard (_M_X86 dans MSVS, __i386__, __arm__ dans GCC, etc.).

Existe-t-il un moyen standard de détecter l'architecture pour laquelle je construis? Sinon, existe-t-il une source pour une liste complète de ces définitions pour divers compilateurs, comme un en-tête avec tous les passe-partout #ifdefs?

76
Alex B

Voici quelques informations sur Macros d'architecture prédéfinies et d'autres types de macros prédéfinies.

Cette question demande où ils sont définis dans le code source de GCC.

72
Serge

Il n'y a pas de norme inter-compilateur, mais chaque compilateur a tendance à être assez cohérent. Vous pouvez créer un en-tête qui ressemble à ceci:

#if MSVC
#ifdef _M_X86
#define Arch_X86
#endif
#endif

#if GCC
#ifdef __i386__
#define Arch_X86
#endif
#endif

Il n'y a pas grand chose à faire pour une liste complète, car il y a des milliers de compilateurs mais seulement 3-4 largement utilisés (Microsoft C++, GCC, Intel CC, peut-être TenDRA?). Décidez simplement des compilateurs que votre application prendra en charge, répertoriez leurs # définitions et mettez à jour votre en-tête si nécessaire.

15
John Millikin

Si vous souhaitez sauvegarder toutes les fonctionnalités disponibles sur une plate-forme particulière, vous pouvez exécuter GCC comme:

gcc -march=native -dM -E - </dev/null

Il viderait des macros comme #define __SSE3__ 1, #define __AES__ 1, etc.

5
Wei Shen

Si vous voulez une solution de compilateur croisé, utilisez simplement Boost.Predef qui contient

  • BOOST_Arch_ pour l'architecture système/CPU pour laquelle on compile.
  • BOOST_COMP_ pour le compilateur utilisé.
  • BOOST_LANG_ pour les normes linguistiques, on compile.
  • BOOST_LIB_C_ et BOOST_LIB_STD_ pour la bibliothèque standard C et C++ utilisée.
  • BOOST_OS_ pour le système d'exploitation que nous compilons.
  • BOOST_PLAT_ pour les plates-formes au-dessus du système d'exploitation ou des compilateurs.
  • BOOST_ENDIAN_ pour l'endianité de la combinaison os et architecture.
  • BOOST_HW_ pour les fonctionnalités spécifiques au matériel.
  • BOOST_HW_SIMD pour la détection SIMD (Single Instruction Multiple Data).

Par exemple

#if defined(BOOST_Arch_X86)
    #if BOOST_Arch_X86_64
        std::cout << "x86_64 " << BOOST_Arch_X86_64 << " \n";
    #Elif BOOST_Arch_X86_32
        std::cout << "x86 " << BOOST_Arch_X86_32 << " \n";
    #endif
#Elif defined(BOOST_Arch_ARM)
    #if _M_ARM
        std::cout << "ARM " << _M_ARM << " \n";
    #Elif _M_ARM64
        std::cout << "ARM64 " << _M_ARM64 << " \n";
    #endif
#endif

Vous pouvez en savoir plus sur son utilisation ici

4
phuclv

Il n'y a rien de standard. Brian Hook en a documenté un tas dans son "Portable Open Source Harness", et essaie même d'en faire quelque chose de cohérent et utilisable (ymmv à ce sujet). Voir l'en-tête posh.h sur ce site:

Remarque, le lien ci-dessus peut vous obliger à entrer un faux identifiant/mot de passe en raison d'une attaque DOS il y a quelque temps.

3
Michael Burr