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?

È stato utile?

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

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);
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top