2008-10-02 14 views
18

En una función C++ necesito que el compilador elija un bloque diferente si está compilando para una arquitectura de 64 bits.¿Cómo puedo detectar si estoy compilando para una arquitectura de 64 bits en C++

Conozco una manera de hacerlo para MSVC++ y g ++, así que lo publicaré como respuesta. Sin embargo, me gustaría saber si hay una mejor manera (más elegante que funcionaría para todos los compiladores/todas las arquitecturas de 64 bits). Si no hay una manera mejor, ¿qué otras macros predefinidas debo buscar para ser compatible con otros compiladores/arquitecturas?

+0

pregunta similares pedido [aquí en SO] (http://stackoverflow.com/ questions/152016/detecting-cpu-architecture-compile-time) ... con una gran respuesta. – paxos1977

Respuesta

9

¿Por qué la elección de 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 número entero, use sizeof(int) == 8.

Mi punto es que el nombre de la arquitectura en sí raramente debería marcar la diferencia. Verifica solo lo que necesita verificar, para los fines de lo que va a hacer. Su pregunta no cubre muy claramente cuál es su propósito del cheque. Lo que está preguntando es similar a tratar de determinar si DirectX está instalado al consultar la versión de Windows. Tiene más herramientas portátiles y genéricas a su disposición.

+2

sizeof (int) no es un buen ejemplo. Depende del compilador. Probé en Linux de 64 bits con g ++ y tenía 4 bytes de longitud. Mejor use sizeof (void *) para determinar architecutre. Pero no estoy seguro de si es igual en todas las máquinas. – klew

+1

@klew, creo que echas de menos el punto de Flodin: "Revisas solo lo que debes verificar, para los fines de lo que vas a hacer". – foraidt

+0

Pero ninguno funciona en el preprocesador, p. '#if sizeof (int) == 4' - ya que el preprocesador no permite' sizeof' en las expresiones #if. – greggo

18

Esto funciona para MSVC++ y g ++:

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

... pero no funciona si tiene como objetivo ARM64 o cualquier otra arquitectura. – DarkDust

7

Raymond covers this.

+0

Esto es específico de Visual C++. – rdb

+0

@rdb La primera parte es, luego va * Si no quiere vincularse a un compilador en particular, tendrá que ...* – GSerg

+0

¡Ese artículo es engañoso e incorrecto! Prueba 'ifdef _X86_' en Visual Studio sin incluir nada. – Pavel

1

Si estás compilando para la plataforma Windows, se debe utilizar:

#ifdef _WIN64 

El compilador MSVC define que para ambos plataformas x64 e ia64 (no querrás 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 diferencia sutil. WIN64 (sin el subrayado inicial) está definido por el SDK (o la configuración de compilación). Como esto está definido por SDK/build config, debería funcionar igual de bien con gcc.

2
#ifdef _LP64 

Obras en ambas plataformas

+0

¿No es Windows ILP64, sin embargo? –

-3

Si su uso de Windows, su probablemente mejor para obtener la variable de entorno "PROCESSOR_ARCHITECTURE" del registro porque sizeof (PVOID) será igual a 4 si es 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); 
    } 
+2

Esto es tiempo de ejecución. OP está pidiendo tiempo de compilación. – tibur

14

Una manera independiente de la arquitectura para la detección de 32 bits y de 64 bits se basa 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 
Cuestiones relacionadas