¿Cómo puedo detectar si estoy compilando para una arquitectura de 64 bits en C ++?

StackOverflow https://stackoverflow.com/questions/163058

  •  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?

¿Fue útil?

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

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);
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top