Come posso rilevare se sto compilando per un'architettura a 64 bit in C ++
-
03-07-2019 - |
Domanda
In una funzione C ++ ho bisogno che il compilatore scelga un blocco diverso se si sta compilando per un'architettura a 64 bit.
Conosco un modo per farlo per MSVC ++ e g ++, quindi lo posterò come risposta. Tuttavia, vorrei sapere se esiste un modo migliore (più elegante che funzionerebbe per tutti i compilatori / tutte le architetture a 64 bit). Se non esiste un modo migliore, quali altre macro predefinite dovrei cercare per essere compatibile con altri compilatori / architetture?
Soluzione
Perché scegli un blocco rispetto all'altro? Se la tua decisione si basa sulla dimensione di un puntatore, usa sizeof (void *) == 8
. Se la tua decisione si basa sulla dimensione di un numero intero, usa sizeof (int) == 8
.
Il mio punto è che il nome dell'architettura stessa raramente dovrebbe fare la differenza. Controlli solo ciò che devi controllare, ai fini di ciò che stai per fare. La tua domanda non copre molto chiaramente qual è il tuo scopo del controllo. Quello che stai chiedendo è simile a provare a determinare se DirectX è installato eseguendo una query sulla versione di Windows. Hai strumenti più portatili e generici a tua disposizione.
Altri suggerimenti
Un modo indipendente dall'architettura per rilevare build a 32 e 64 bit in C e C ++ è simile al seguente:
// 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
Funziona con MSVC ++ e g ++:
#if defined(_M_X64) || defined(__amd64__)
// code...
#endif
Raymond copre questo .
#ifdef _LP64
Funziona su entrambe le piattaforme
Ecco una buona panoramica per Mac OS X:
http://developer.apple.com/documentation/Darwin/Conceptual/64bitPorting
Se stai compilando per la piattaforma Windows, dovresti usare:
#ifdef _WIN64
Il compilatore MSVC lo definisce sia per piattaforme x64 che ia64 (non vuoi tagliare quel mercato, vero?). Non sono sicuro che gcc faccia lo stesso, ma dovrebbe farlo in caso contrario.
Un'alternativa è
#ifdef WIN64
che ha una differenza sottile. WIN64 (senza il carattere di sottolineatura iniziale) è definito dall'SDK (o dalla configurazione della build). Dato che questo è definito da SDK / build config, dovrebbe funzionare altrettanto bene con gcc.
Se utilizzi Windows, probabilmente è meglio ottenere " PROCESSOR_ARCHITECTURE " variabile d'ambiente dal registro perché sizeof (PVOID) sarà uguale a 4 se è un processo a 32 bit in esecuzione su un sistema operativo a 64 bit (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);
}