¿Cómo puedo detectar si estoy compilando para una arquitectura de 64 bits en C ++?
-
03-07-2019 - |
Pregunta
En una función de C ++ necesito que el compilador elija un bloque diferente si está compilando para una arquitectura de 64 bits.
Sé una forma de hacerlo para MSVC ++ y g ++, así que lo publicaré como respuesta. Sin embargo, me gustaría saber si hay una forma mejor (más elegante que funcionaría para todos los compiladores / todas las arquitecturas de 64 bits). Si no hay una mejor manera, ¿qué otras macros predefinidas debo buscar para ser compatible con otras compilaciones / arquitecturas?
Solución
¿Por qué eliges un bloque sobre el otro? Si su decisión se basa en el tamaño de un puntero, use sizeof (void *) == 8
. Si su decisión se basa en el tamaño de un entero, use sizeof (int) == 8
.
Mi punto es que el nombre de la arquitectura en sí rara vez debería hacer alguna diferencia. Usted solo verifica lo que necesita verificar, a los fines de lo que va a hacer. Su pregunta no cubre claramente cuál es su propósito del cheque. Lo que está preguntando es como intentar determinar si DirectX está instalado consultando la versión de Windows. Tienes más herramientas portátiles y genéricas a tu disposición.
Otros consejos
Una forma independiente de la arquitectura para detectar compilaciones de 32 y 64 bits en C y C ++ se ve así:
// 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
Esto funciona para MSVC ++ y g ++:
#if defined(_M_X64) || defined(__amd64__)
// code...
#endif
Raymond cubre esto .
#ifdef _LP64
Funciona en ambas plataformas
Aquí hay un buen resumen para Mac OS X:
http://developer.apple.com/documentation/Darwin/Conceptual/64bitPorting
Si está compilando para la plataforma Windows, debe usar:
#ifdef _WIN64
El compilador de MSVC define eso para las plataformas x64 e ia64 (no quieres cortar ese mercado, ¿verdad?). No estoy seguro de si gcc hace lo mismo, pero debería hacerlo si no lo hace.
Una alternativa es
#ifdef WIN64
que tiene una sutil diferencia. WIN64 (sin el guión bajo) está definido por el SDK (o la configuración de compilación). Como esto está definido por el SDK / build config, debería funcionar igual de bien con gcc.
Si está usando Windows, probablemente sea mejor obtener " PROCESSOR_ARCHITECTURE " variable de entorno del registro porque sizeof (PVOID) será igual a 4 si se trata de un proceso de 32 bits que se ejecuta en un sistema operativo de 64 bits (también conocido como 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);
}