Mein Code:
#include <stdio.h>
#include <limits.h>
int main()
{
char c = CHAR_MAX;
c += 1;
printf("CHAR_MIN=%d CHAR_MAX=%d c=%d (%c)\n", CHAR_MIN, CHAR_MAX, c, c);
}
Ausgabe:
CHAR_MIN=-128 CHAR_MAX=127 c=-128 ()
Wir sehen, dass, wenn wir eine char
Variable inkrementieren CHAR_MAX
, diese umbrochen wird CHAR_MIN
. Ist dieses Verhalten garantiert? Oder handelt es sich um undefiniertes oder implementierungsspezifisches Verhalten? Was sagt der C99-Standard dazu?
[Hinweis: Was passiert, wenn char oder C ein Wert größer als CHAR_MAX (127) gegeben wird - warum wird char c = 129 in -127 konvertiert? geht auf diese Frage nicht ein, weil sie über das Zuweisen eines Werts außerhalb des Bereichs sprechen, ohne einen Wert einem Wert außerhalb des Bereichs zu erhöhen.]
c
char
language-lawyer
standards
integer-overflow
Einsamer Lernender
quelle
quelle
Antworten:
Die Frage ist zweifach: Erstens ist
anders bewertet als
und die Antwort ist nein, ist es nicht , weil C11 / C18 6.5.16.2p3 :
Dann ist die Frage, was in passiert
c = c + 1
. Hier werden die Operanden zu+
üblichen arithmetischen Umwandlungen durchlaufen, undc
und1
werden daher gefördertint
, es sei denn , eine wirklich verrückte Architektur erfordert , dasschar
wird gefördertunsigned int
. Die Berechnung von+
wird dann ausgewertet und das Ergebnis vom Typint
/unsigned int
zurück in konvertiertchar
und darin gespeichertc
.Es gibt 3 implementierungsdefinierte Möglichkeiten, wie dies bewertet werden kann:
CHAR_MIN
ist 0 und daherchar
ohne Vorzeichen.Entweder
char
wird dann gefördertint
oderunsigned int
und wenn es ein gefördert wirdint
, dannCHAR_MAX + 1
wird zwangsläufig in ein passtint
auch, und nicht überläuft oder wennunsigned int
es auf Null passen oder umwickeln können. Wenn der resultierende Wert, der numerisch entwederCHAR_MAX + 1
oder0
nach der Modulo-Reduktion ist, zurück zuc
, nach der Modulo-Reduktion, wird er 0, dhCHAR_MIN
Andernfalls
char
wird signiert. WennCHAR_MAX
es kleiner als istINT_MAX
,CHAR_MAX + 1
passt das Ergebnis von zuint
und der Standard C11 / C18 6.3.1.3p3 gilt für die Konvertierung, die bei der Zuweisung erfolgt :Wenn iff
sizeof (int) == 1
undchar
signiert ist,char
wird es zu einem hochgestuftint
, undCHAR_MAX == INT_MAX
=>CHAR_MAX + 1
verursacht einen ganzzahligen Überlauf und das Verhalten ist undefiniert .Dh die möglichen Ergebnisse sind:
Wenn
char
es sich um einen vorzeichenlosen Integer-Typ handelt, ist das Ergebnis immer0
, dhCHAR_MIN
.Andernfalls
char
handelt es sich um einen vorzeichenbehafteten Ganzzahltyp, und das Verhalten ist implementierungsdefiniert / undefiniert:CHAR_MIN
oder ein anderer implementierungsdefinierter Wert,sizeof (char) == sizeof (int)
.Alle Zuwachs Operationen
c = c + 1
,c += 1
,c++
und++c
haben die gleichen Nebenwirkungen auf der gleichen Plattform. Der ausgewertete Wert des Ausdrucksc++
ist der Wertc
vor dem Inkrement. für die anderen drei ist es der Wert vonc
nach dem Inkrement.quelle
sizeof(int) == 1
würde erfordernCHAR_BITS >= 16
, richtig?<pedantic>
IDK überCHAR_BITS
aberCHAR_BIT
würde>= 16</pedantic>
.char
immer standardmäßig ohne Vorzeichen sein sollte.