2008-10-02 6 views
18

Dans une fonction C++, j'ai besoin que le compilateur choisisse un bloc différent s'il compile pour une architecture 64 bits.Comment puis-je détecter si je compile pour une architecture 64 bits en C++?

Je connais un moyen de le faire pour MSVC++ et g ++, donc je vais le poster comme une réponse. Cependant je voudrais savoir s'il y a un meilleur moyen (plus élégant qui fonctionnerait pour toutes les architectures de compilateurs/toutes les 64 bits). S'il n'y a pas de meilleur moyen, quelles autres macros prédéfinies dois-je rechercher pour être compatible avec d'autres compilateurs/architectures?

+0

question similaire posée [ici sur le SO] (http://stackoverflow.com/ questions/152016/detection-cpu-architecture-compile-time) ... avec une très bonne réponse. – paxos1977

Répondre

9

Pourquoi choisissez-vous un bloc sur l'autre? Si votre décision est basée sur la taille d'un pointeur, utilisez sizeof(void*) == 8. Si votre décision est basée sur la taille d'un nombre entier, utilisez sizeof(int) == 8. Mon point est que le nom de l'architecture elle-même devrait rarement faire la différence. Vous ne vérifiez que ce que vous devez vérifier, aux fins de ce que vous allez faire. Votre question ne couvre pas très clairement le but de votre vérification. Ce que vous demandez est similaire à essayer de déterminer si DirectX est installé en interrogeant la version de Windows. Vous avez plus d'outils portables et génériques à votre disposition.

+2

sizeof (int) n'est pas un bon exemple. Cela dépend du compilateur. J'ai essayé sur Linux 64 bits avec g ++ et c'était 4 octets de long. Mieux vaut utiliser sizeof (void *) pour déterminer l'architecutre. Mais je ne sais pas si c'est la même chose sur toutes les machines. – klew

+1

@klew, je pense que vous avez manqué le point de Flodin: "Vous ne vérifiez que ce que vous devez vérifier, pour ce que vous allez faire." – foraidt

+0

Mais ni l'un ni l'autre ne fonctionne en préprocesseur, par ex. '#if sizeof (int) == 4' - puisque le préprocesseur n'autorise pas' sizeof' dans les expressions #if. – greggo

18

Cela fonctionne pour MSVC++ et g ++:

#if defined(_M_X64) || defined(__amd64__) 
    // code... 
#endif 
+0

... mais ne fonctionne pas si vous ciblez ARM64 ou toute autre architecture. – DarkDust

7

Raymond covers this.

+0

Ceci est spécifique à Visual C++. – rdb

+0

@rdb La première partie est, alors ça passe * Si vous ne voulez pas vous attacher à un compilateur particulier, vous devrez ...* – GSerg

+0

Cet article est trompeur et faux! Essayez 'ifdef _X86_' dans Visual Studio sans inclure quoi que ce soit. – Pavel

1

Si vous compilez pour la plate-forme Windows, vous devez utiliser:

#ifdef _WIN64 

Le compilateur MSVC définit que pour les plates-formes x64 et ia64 (vous ne voulez pas couper ce marché, n'est-ce pas?). Je ne suis pas sûr si gcc fait la même chose - mais il devrait le faire si ce n'est pas le cas.

Une alternative est

#ifdef WIN64 

qui a une différence subtile. WIN64 (sans le trait de soulignement principal) est défini par le SDK (ou la configuration de construction). Puisque ceci est défini par le fichier SDK/build config, cela devrait fonctionner aussi bien avec gcc.

2
#ifdef _LP64 

Travaux sur les deux plates-formes

+0

Windows ILP64 n'est pas, cependant? –

-3

Si votre utilisation de Windows, votre probablement mieux pour obtenir la variable d'environnement « PROCESSOR_ARCHITECTURE » du registre parce que sizeof (PVOID) sera égal à 4 si son processus 32bit en cours d'exécution sur un système d'exploitation 64 bits (aka WOW64):

if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\CurrentControlSet\\Control\\Session Manager\\Environment"), 0, KEY_READ, &hKey) == ERROR_SUCCESS) { 
     LPSTR szArch = new CHAR[100]; 

     ZeroMemory(szArch, 100); 

     if (RegQueryValueEx(hKey, _T("PROCESSOR_ARCHITECTURE"), NULL, NULL, (LPBYTE)szArch, &dwSize) == ERROR_SUCCESS) { 
      if (strcmp(szArch, "AMD64") == 0) 
       this->nArchitecture = 64; 
      else 
       this->nArchitecture = 32; 
     } else { 
      this->nArchitecture = (sizeof(PVOID) == 4 ? 32 : 64); 
     } 

     RegCloseKey(hKey); 
    } 
+2

Ceci est l'exécution. L'OP demande le temps de compilation. – tibur

14

Un moyen indépendant de l'architecture pour détecter 32 bits et 64 bits en C et construit C++ ressemble à ceci:

// C 
#include <stdint.h> 

// C++ 
#include <cstdint> 

#if INTPTR_MAX == INT64_MAX 
// 64-bit 
#elif INTPTR_MAX == INT32_MAX 
// 32-bit 
#else 
#error Unknown pointer size or missing size macros! 
#endif 
Questions connexes