Domanda

Come dice il titolo, c'è un modo elegante e sicuro per determinare se l'architettura è 32bit o 64bit. Con eleganti, si può pensare a modo preciso, corretto, insomma, pulito e intelligente. Di sicuro, pensare alla sicurezza in termini di standard C89 / C99, e l'indipendenza del sistema operativo.

È stato utile?

Soluzione

La dimensione dei puntatori non è davvero una buona cosa per testare - non c'è molto in serie C che si può fare con il risultato di tale prova comunque

.

Il mio suggerimento è di prova ((size_t)-1), le dimensioni dell'oggetto più grande che comprende C:

    if ((size_t)-1 > 0xffffffffUL)
    {
            printf("> 32 bits\n");
    }
    else
    {
            printf("<= 32 bits\n");
    }

Se è maggiore di 0xffffffffUL allora si può in linea di principio avere oggetti più grandi di byte 2**32 - 1, che sembra un test più significativo di un nebuloso "32 bit contro i 64 bit".

(ad esempio, se si sa che il valore massimo di size_t è solo 2**32 - 1, allora non ha senso cercare di mmap() una regione più grande di 1 o 2 GB).

Altri suggerimenti

risposta breve: non

risposta lunga: dipende da troppe combinazioni di OS / compilatore. Per esempio in fase di esecuzione, su linux è possibile interrogare il filesystem proc, mentre su Windows è possibile interrogare il registro.

Si può dimostrare che il compilatore che vengono utilizzati per la compilazione ha un 32/64 bits di destinazione utilizzando qualcosa di simile:

bool is_32bit() {
    return sizeof(int *) == 4;
} 

bool is_64bit() {
    return sizeof(int *) == 8;
} 

questo potrebbe opere in alcune ipotesi (per esempio funziona in fase di esecuzione). È possibile cercare in fase di compilazione #define per la vostra piattaforma, ma è un casino ben noto.

Se si utilizza GCC (come indicato nei tag), è possibile verificare, come test in fase di compilazione

#if __SIZEOF_POINTER__ == 8

per scoprire se si tratta di un sistema a 64 bit. Assicurarsi che la versione GCC si sta utilizzando definisce __SIZEOF_POINTER__ a tutti prima di utilizzarlo.

Il modo più comune è quello di testare sizeof(void*) e sizeof(int) (notare che essi non devono necessariamente essere lo stesso).

Un'altra possibilità su CPU x86 / x64 è testare per la bandiera 'lm'. Se è presente la CPU capisce il set di istruzioni AMD64.

Una tecnica sicura e portatile è purtroppo impossibile (perché sicuro e portatile permette solo le regole del C standard).

sizeof(int) con alcuni dei compilatori più comuni può dare 4 per una piattaforma a 32 bit e 8 per una piattaforma a 64 bit, ma questo non è garantito. Tutto lo standard C dice è che un int dovrebbe essere la dimensione 'naturale' per i calcoli sul bersaglio, e così molti compilatori hanno lasciato sizeof (int) come 4 anche in un mondo a 64 bit, per il fatto che si tratta di 'sufficiente' .

sizeof(void*) è meglio perché un puntatore deve essere la dimensione appropriata per affrontare l'intero spazio di indirizzamento. sizeof(void*) è quindi probabile per darvi 4 o 8 a seconda dei casi. Tecnicamente, però, anche questo non è garantito come sizeof ti dà il numero di byte necessari per memorizzare qualcosa, e un byte non deve essere di 8 bit. Un byte è tecnicamente la più piccola unità indirizzabile della memoria che avviene solo per essere 8 bit sulla maggior parte delle piattaforme di persone sono abituati. 8 bit indirizzabile è molto comune, ma lavoro con chip che sono 16 bit indirizzabili e dimensione di parola di 16 bit (così sizeof(int) è 1). Quindi, se la vostra dimensione in byte non è a 8 bit, quindi sizeof(void*) potrebbe darvi una serie di valori.

D'altra parte, se si sta semplicemente cercando di distinguere tra x86 e x64 (32 bit e 64 processori bit PC) quindi sizeof (void *) saranno sufficienti, e portatili compilatori tutto.

32 bit sulla riva codice o 32 bit sulla banca dati. :-) 8086 processori avevano dati a 16 bit con memoria codice a 20 bit. Inoltre, le moderne macchine Havard fanno cose strane con la separazione di codice / dati ...

Si potrebbe verificare l'istruzione cpuid per processori x86. Altre famiglie di processori non possono avere un tale istruzione ... YMMV.

int iedx;

__asm
{

mov eax, 0x80000001;
cpuid;
mov, iedx,edx;
}

     if (iedx & (1 << 29))
       {
        return 1;
       }
     return 0;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top