Comment détecter si je compile pour une architecture 64 bits en C ++
-
03-07-2019 - |
Question
Dans une fonction C ++, le compilateur doit choisir un bloc différent s'il compile pour une architecture 64 bits.
Je connais un moyen de le faire pour MSVC ++ et g ++, je vais donc le poster en tant que réponse. Cependant, j'aimerais savoir s'il existe un meilleur moyen (plus élégant qui conviendrait pour tous les compilateurs / toutes les architectures 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?
La solution
Pourquoi choisissez-vous un bloc plutôt qu'un 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 entier, utilisez sizeof (int) == 8
.
Mon idée est que le nom de l'architecture elle-même devrait rarement faire la différence. Vous ne cochez 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 revient à 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.
Autres conseils
Une méthode indépendante de l'architecture pour détecter les constructions 32 bits et 64 bits en C et C ++ se présente comme suit:
// 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
Ceci fonctionne pour MSVC ++ et g ++:
#if defined(_M_X64) || defined(__amd64__)
// code...
#endif
Raymond couvre cette question .
#ifdef _LP64
Fonctionne sur les deux plates-formes
Voici un bon aperçu de Mac OS X:
http://developer.apple.com/documentation/Darwin/Conceptual/64bitPorting
Si vous compilez pour la plate-forme Windows, vous devez utiliser:
#ifdef _WIN64
Le compilateur MSVC définit cela pour les plates-formes x64 et ia64 (vous ne voulez pas couper ce marché, n'est-ce pas?). Je ne sais pas 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 tiret bas) est défini par le SDK (ou la configuration de construction). Puisque ceci est défini par le SDK / build config, cela devrait fonctionner aussi bien avec gcc.
Si vous utilisez Windows, vous ferez probablement mieux d'obtenir le "PROCESSOR_ARCHITECTURE". Variable d’environnement du registre car sizeof (PVOID) sera égal à 4 s’il s’agit d’un processus 32 bits exécuté sur un système d’exploitation 64 bits (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);
}