Como posso detectar se eu estou compilando para uma arquitetura de 64bits em C ++
-
03-07-2019 - |
Pergunta
Em uma função C ++ que eu preciso o compilador para escolher um bloco diferente se ele está compilando para uma arquitetura de 64 bits.
Eu sei uma maneira de fazê-lo para MSVC ++ e g ++, então eu vou postá-lo como uma resposta. No entanto, eu gostaria de saber se existe uma maneira melhor (mais elegante que iria trabalhar para todos os compiladores / todos os 64 bits arquiteturas). Se não houver uma maneira melhor, que outras macros pré-definido que devo procurar, a fim de ser compatível com outros compilador / arquiteturas?
Solução
Por que você está escolhendo um bloco sobre o outro? Se sua decisão é baseada no tamanho de um ponteiro, use sizeof(void*) == 8
. Se sua decisão é baseada no tamanho de um inteiro, sizeof(int) == 8
uso.
Meu ponto é que o nome da arquitetura em si deve raramente faz qualquer diferença. Você verifica apenas o que você precisa verificar, para efeitos do que você está indo fazer. Sua pergunta não cobrem muito claramente o seu objetivo da verificação é. O que você está pedindo é semelhante a tentar determinar se o DirectX está instalado consultando a versão do Windows. Você tem mais ferramentas portáteis e genéricos à sua disposição.
Outras dicas
Um independente de arquitetura maneira de detectar 32-bit e 64-bit constrói em C e C ++ aparência como esta:
// 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
Isso funciona para MSVC ++ e g ++:
#if defined(_M_X64) || defined(__amd64__)
// code...
#endif
#ifdef _LP64
Obras em ambas as plataformas
Eis um resumo bom para Mac OS X:
http://developer.apple.com/documentation/Darwin/Conceptual/64bitPorting
Se você está compilando para a plataforma Windows, você deve usar:
#ifdef _WIN64
Os define compilador MSVC que tanto para x64 e ia64 plataformas (você não quer cortar esse mercado, não é?). Eu não tenho certeza se gcc faz o mesmo -. Mas deve se isso não acontecer
Uma alternativa é
#ifdef WIN64
que tem uma diferença sutil. Win64 (sem o sublinhado esquerda) é definida pelo SDK (ou a configuração de construção). Uma vez que este é definido pela configuração SDK / build, ele deve funcionar tão bem com gcc.
Se o seu usando o Windows, o seu provavelmente melhor para obter o "PROCESSOR_ARCHITECTURE" variável de ambiente a partir do registro porque sizeof (PVOID) será igual a 4 se é um processo de 32 bits rodando em um sistema operacional de 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);
}