C++ 11 §3.9.1/4, vollständige Zitat:
” Unsigned Integer, erklärt unsigned
, müssen die Gesetze der Arithmetik Modulo gehorchen 2 n wo n das ist Nummer von Bits in der Wertdarstellung dieser bestimmten Größe der ganzen Zahl.
Abgesehen von der etwas irreführenden Formulierung über “ erklärt unsigned
” könnte dies gelten scheint, dass jeder arithmetischer Ausdruck, der nur Argument von einem gegebenen Typ ohne Vorzeichen beinhalten, um ein Ergebnis Modulo ergeben wird 2 n für diese Art .
Jedoch gibt es keine arithmetische Ausdrücke auf allen für unsigned Typen von niedrigeren Umwandlungs Rang als int
: alle Argumente in einem scheinbaren solchen Expressions konvertiert bis (1) mindestens int
, oder in Abhängigkeit von der Anzahl Bereiche von die C++ Implementierung, bis zu unsigned int
.
Als Ergebnis a*b
wo a
und b
sind unsigned short
Werte, (2) kann formal nicht definiertes Verhalten haben. Weil es kein unsigned short
Ausdruck ist. Es ist (in der Praxis) ein int
Ausdruck.
Das heißt, mit einem vernünftigen Compiler, der keine speziellen Gehäuse einführt, wo es formal UB, und mit in-Praxis 8-Bit-Bytes und unsigned short
max-Wert, der durch int
ist darstellbare bemerkt, und gemeinsame Komplement vorzeichenbehaftete Ganzzahl-Darstellung der beiden, das Ergebnis wird, wenn es zurück in unsigned short
konvertiert wird, sein, als ob es modulare Arithmetik im Bereich von unsigned short
wäre. Das ist, weil Zweierkomplement, an der Maschinencode-Ebene, nur modulare Arithmetik mit einem Bereich zentrierte auf 0.
(1) In der Praxis wird man in der Regel einen 8 Bit pro Byte verwenden Implementierung, wo der Maximalwert von unsigned short
passt gut in die int
Bereich, so in der Praxis sprechen wir über eine Umwandlung bis int
.
(2) Eg, für 16-Bit unsigned short
und 32-Bit-int
, (2 -1) = 2 -2 × 2 +1> 2 -1, wobei der letzte Wert der maximale positive Wert int
ist.
Ja. Das Ergebnis ist, keine Arithmetik mit vorzeichenlosen Typen eines niedrigeren Umwandlungsrangs als "int" auszuführen. Eine einfachere Regel besteht darin, keine vorzeichenbehafteten Typen für Zahlen zu verwenden, sondern sie für Bit-Fiddling zu verwenden. –
Ja, dies ist ein vorzeichenbehafteter ganzzahliger Überlauf, der UB verursacht. Eine lästige historische Warze, und sie kann in Verkleidung auftreten, weil 'uint16_t' oft als typedef für' unsigned short' implementiert wird. Theoretisch könnte das gleiche Problem sogar mit "uint32_t" auftreten, da es nichts gibt, was einen Compiler stoppt, der zum Beispiel "kurz" 32-Bit auf einem System mit 64-Bit "int" macht. –
@ M.M: Eigentlich ist hier nichts besonderes an "short". Jeder vorzeichenlose Typ, der kleiner als "int" ist, wird vor dem Ausführen von arithmetischen Operationen zu "int" hochgestuft. Dies gilt insbesondere für "uint32_t", wenn "int" 64-Bit ist. –