2015-05-19 7 views
6

Un numero senza firma int può contenere solo 32 bit di dati. Perché il compilatore non dà un errore quando assegno ad esso un valore maggiore di quello che può contenere?Perché questo int unsigned contiene più dati di quanti ne ha per la memoria?

Ho provato altri valori diversi e non dà ancora errori.

int main() 
{ 
    unsigned int mem = 0x89678456543454345934; 
    cout << mem; 

    return 0; 
} 
+2

Poiché il comportamento dell'overflow dei numeri interi senza segno è ben definito. O stai chiedendo perché è così, come in, perché i progettisti di C++ non hanno reso questo un errore? – juanchopanza

+4

FWIW probabilmente dovresti aumentare il livello di avviso. –

+0

sì, perché è – wazeeer

risposta

12

Questo perché 0x89678456543454345934 è maggiore di std::numeric_limits<unsigned_int>::max(). Tuttavia, i tipi unsigned racchiudono il loro valore massimo, quindi se il lato destro è rappresentabile da un tipo intero hai un comportamento ben definito. In tal caso il risultato è 0x89678456543454345934 mod std::numeric_limits<unsigned_int>::max.

EDIT

Il lato destro del tuo incarico è un integer literal. Per rappresentarlo, il compilatore usa il primo tipo (ordinato in base alla sua dimensione) in cui il letterale intero può andare bene. Se non esiste un tale tipo, quindi il programma è malformato. Il valore decimale della vostra costante è:

648873758694578209446196L 

Sulla mia macchina, sia per clang ++ e g ++ std::numeric_limits<unsigned long long>::max() è 18446744073709551615, che è più piccolo della tua costante. Sembra che il tuo programma sia malformato, a meno che il compilatore non usi più di 64 bit per rappresentare unsigned long long, cosa di cui dubito fortemente. Come @juanchopanza osservato, clang ++ rifiuta di compilare il codice, con l'errore

error: integer constant is larger than the largest unsigned integer type

g ++ comunque va avanti e lo compila, emettendo solo un avviso

warning: large integer implicitly truncated to unsigned type

L'avvertimento è piuttosto confusa, in quanto si riferisce a destra, non alla ulteriore conversione a unsigned int, per il quale si ottiene

warning: large integer implicitly truncated to unsigned type [-Woverflow]

Sulla mia macchina std::numeric_limits<unsigned int>::max() è 4294967295, e quindi 648873758694578209446196L % 4294967295 è 3633002191L. Tuttavia quando eseguo il tuo programma ottengo 1412716852. Questo accade perché il programma è mal formato e sfortunatamente il compilatore non emette un errore (non è obbligatorio dallo standard) ma solo un avvertimento.

+2

Clang mi dà un errore più rilevante: 'errore: il letterale intero è troppo grande per essere rappresentato in qualsiasi tipo intero ' – juanchopanza

+0

yup g ++ modifica i valori di mem da 9535901844731353396 a 1412716852 –

Problemi correlati