Nachdem ich die Frage 32 bit unsigned multiply on 64 bit causing undefined behavior? hier auf StackOverflow gelesen hatte, begann ich darüber nachzudenken, ob typische arithmetische Operationen an kleinen vorzeichenlosen Typen zu undefiniertem Verhalten gemäß dem C99-Standard führen könnten.Kann vorzeichenlose Ganzzahlinkrementierung zu undefiniertem definiertem Verhalten führen?
Nehmen wir zum Beispiel den folgenden Code:
#include <limits.h>
...
unsigned char x = UCHAR_MAX;
unsigned char y = x + 1;
Die x
Variable auf die maximale Größe für den Datentyp unsigned char
initialisiert wird. Die nächste Zeile ist das Problem: Der Wert x + 1
ist größer als UCHAR_MAX
und kann nicht in der unsigned char
Variablen y
gespeichert werden.
Ich glaube, das Folgende ist was tatsächlich vorkommt.
- Die Variable
x
ersten Datentypint
(Abschnitt 6.3.1.1/2) gefördert wird, wird dann als Datentypx + 1
int
ausgewertet.
Angenommen, es ist eine Implementierung, wo INT_MAX
und UCHAR_MAX
gleich sind - x + 1
in einer signierten Integer-Überlauf führen würde. Bedeutet dies, dass das Inkrementieren der Variablen x
trotz eines vorzeichenlosen Integer-Typs zu einem undefinierten Verhalten aufgrund eines möglichen vorzeichenbehafteten Integer-Überlaufs führen kann?
Wenn 'sizeof (unsigned char) == sizeof (int)', gilt das erste Szenario. – chux
@chux Warum würde eine Promotion nicht stattfinden, wenn ein 'int' den Wert darstellen kann? –
Ich überprüfe "6.3.1.8 Übliche arithmetische Konvertierungen" Dies scheint zuerst zu gelten "Andernfalls, wenn der Operand, der vorzeichenlosen Integer-Typ hat Rang größer oder gleich dem Rang des Typs des anderen Operanden, dann der Operand mit signierten Integer-Typ wird in den Typ des Operanden mit unsigned Integer-Typ konvertiert. " Das kommt vor dem "Sonst, wenn der Typ des Operanden mit vorzeichenbehafteten Integer-Typ alle Werte des Typs des Operanden mit unsigned integer type ..." -Regel repräsentieren kann. – chux