2015-05-19 5 views
6

Ein unsigned int kann nur 32 Datenbits speichern. Warum gibt der Compiler keinen Fehler, wenn ich ihm einen größeren Wert zuwähle als er halten kann?Warum enthält dieses unsigned int mehr Daten als es Speicher für?

Ich habe andere verschiedene Werte ausprobiert und es gibt immer noch keinen Fehler.

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

    return 0; 
} 
+2

Weil das Verhalten des vorzeichenlosen Integer-Überlaufs gut definiert ist. Oder fragen Sie sich, warum das so ist, warum haben die Entwickler von C++ das nicht zu einem Fehler gemacht? – juanchopanza

+4

FWIW sollten Sie wahrscheinlich Ihre Warnstufe erhöhen. –

+0

ja warum ist das – wazeeer

Antwort

12

Das ist, weil 0x89678456543454345934 größer als std::numeric_limits<unsigned_int>::max() ist. Die Typen unsigned umschließen jedoch ihren Maximalwert. Wenn also die rechte Seite durch einen Integer-Typ dargestellt werden kann, haben Sie ein wohldefiniertes Verhalten. In diesem Fall lautet das Ergebnis 0x89678456543454345934 mod std::numeric_limits<unsigned_int>::max.

EDIT

Die rechte Seite der Zuweisung ist ein integer literal. Um es darzustellen, verwendet der Compiler den ersten Typ (geordnet nach seiner Größe), in den das Ganzzahlliteral passen kann. Wenn es keinen solchen Typ gibt, dann ist das Programm schlecht gebildet. Der Dezimalwert Ihrer Konstante ist:

648873758694578209446196L 

Auf meinem Rechner für beide Klirren ++ und g ++ std::numeric_limits<unsigned long long>::max() ist 18446744073709551615, die kleiner als Ihre konstant ist. Es scheint, dass Ihr Programm dann schlecht gebildet ist, es sei denn, der Compiler verwendet mehr als 64 Bits, um unsigned long long darzustellen, was ich sehr bezweifle. Wie @juanchopanza bemerkt, Klirren ++ weigert geht, den Code zu kompilieren, mit dem Fehler

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

g ++ jedoch voraus und stellt es,

warning: large integer implicitly truncated to unsigned type

nur eine Warnung emittierende

Die Warnung ist ziemlich verwirrend, da sie sich auf der rechten Seite, Sie

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

auf meinem Rechner std::numeric_limits<unsigned int>::max() istnicht auf die weitere Umwandlung in unsigned int, für die bekommenund daher 648873758694578209446196L % 4294967295 ist 3633002191L. Aber wenn ich dein Programm starte, bekomme ich 1412716852. Dies geschieht, weil das Programm schlecht ausgebildet ist, und leider gibt der Compiler keinen Fehler aus (es ist nicht vom Standard vorgeschrieben), sondern nur eine Warnung.

+2

Clang gibt mir einen relevanteren Fehler: 'Fehler: Integer-Literal ist zu groß, um in einem Integer-Typ dargestellt zu werden. ' – juanchopanza

+0

yup g ++ ändert Werte von Mem von 9535901844731353396 zu 1412716852 –