Domanda

Mi sono imbattuto in qualcosa che penso piuttosto strano. Il programma di test

int main(int argc, char* argv[])
{
    cout<<"hello"<<endl;
    long unsigned l = 0x12345678;
    long long unsigned ll =  0x12345678;
    cout<<sizeof(l)<<endl;
    cout<<sizeof(ll)<<endl;
};

L'output è:

hello    
4    
8

Nessuna sorpresa lì. Il long int ha una dimensione di 4 byte e il long long ha una dimensione di 8 byte. Tuttavia, quando lo cambio in modo che il lungo lungo sia assegnato

long long unsigned ll =  0x123456789;

Al momento della compilazione che ottengo

error: integer constant is too large for "long" type

Ora questo stesso test fa Compilare se formo una costruzione a 64 bit usando l'opzione -m64. Sto facendo qualcosa di sbagliato o questo è un bug in GCC?

È stato utile?

Soluzione

Cambiarlo in

long long unsigned ll = 0x123456789ULL; // notice the suffix

Senza il suffisso, il letterale è più grande del massimo unsigned long valore sulla tua macchina e questo, secondo C ++ 03 (ma non C ++ 11, che ha long long), è un comportamento indefinito. Ciò significa che tutto può accadere, incluso un errore a tempo di compilazione.

Inoltre non vale nulla che non ci sia long long In C ++ 03, quindi non è garantito per funzionare, stai facendo affidamento su un'estensione. Probabilmente è meglio che tu sia invece uscito usando C ++ 11.

Altri suggerimenti

La cosa qui è che molte persone sembrano guardare una riga di codice come il tuo:

unsigned long long ll = 0x123456789;   /* ANTI-PATTERN! Don't do this! */

e motivo "Oh, il tipo è unsigned long long, quindi il valore è unsigned long long E viene assegnato ", ma non è così che funziona. avere il proprio tipo, ciò non dipende dal contesto in cui vengono utilizzati. E il tipo di letterali interi è int.

Questo è lo stesso errore di quando la gente lo fa:

const double one_third = 1 / 3;   /* ANTI-PATTERN! Don't do this! */

Pensare "Il tipo a sinistra è double, quindi questo dovrebbe assegnare 0,3333333 ... ". Questo è solo (di nuovo!) Non come funziona. I tipi di letterali divisi sono ancora int, quindi il lato destro valuta esattamente 0, che viene poi convertito in double e conservato nel one_third variabile.

Per qualche ragione, questo comportamento è profondamente non intuitivo per molte persone, motivo per cui ci sono molte varianti della stessa domanda.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top