Ich fange gerade an, C in der Schule zu lernen, ich versuche, die grundlegenden Konzepte zu verstehen.
Unsere Hausaufgaben haben eine Frage,
für jedes int x: x+1 > x
Bestimmen Sie, ob Richtig oder Falsch, geben Sie eine Richtigstellung wenn wahr und Gegenbeispiel falls Falsch.
Ich bin verwirrt, weil uns beigebracht wurde, dass der Typ int aus 32 Bits besteht und dass die ganze Zahl im Binärformat ist. Ist x + 1 1 zum Dezimalwert von 1 addieren?
ist 1
für jeden int
-Wert mit Ausnahme von Wert INT_MAX
wobei INT_MAX + 1
ein Überlauf ist und daher x + 1 > x
Ausdruck ein undefiniertes Verhalten für x
Wert von INT_MAX
ist.
Dies bedeutet tatsächlich, dass ein Compiler das Recht hat, den Ausdruck zu optimieren:
%Vor%von
%Vor% Da INT_MAX + 1
undefiniertes Verhalten ist, hat der Compiler das Recht zu sagen, dass für diesen spezifischen >
Ausdruck INT_MAX + 1
ist > INT_MAX
.
Da der Ausdruck x + 1 > x
ein nicht definiertes Verhalten für x == INT_MAX
ist, ist es auch nicht sicher anzunehmen, dass x + 1 > x
falsch ( 0
) sein kann.
Beachten Sie, dass die Situation völlig anders ist, wenn x
als unsigned int
anstatt als int
deklariert wurde. unsigned int
Operanden werden niemals überlaufen (sie werden umgebrochen): UINT_MAX + 1 == 0
und daher x + 1 > x
ist 0
für x == UINT_MAX
und 1
für alle anderen x
Werte.
Moderne Compiler (wie gcc
) nutzen normalerweise die Möglichkeit, diesen Ausdruck zu optimieren und durch 1
zu ersetzen.
Für die Aufzeichnung gab es einige ernsthafte Sicherheitsprobleme mit bekannten Serverprogrammen, die einen Code wie:
verwenden %Vor% Der Code sollte eine Sicherheitsbedingung auslösen, aber der Compiler würde die if
-Anweisung optimieren (indem er den Ausdruck durch 0
ersetzt) und es einem Angreifer erlauben, eine Privilegien-Eskalation im Serverprogramm zu erhalten (durch Öffnen der Möglichkeit eines ausnutzbaren Pufferüberlaufs, wenn ich mich richtig erinnere).
Hinweis für den 32-Bit-Nummernbereich ist [-2147483648, 2147483647]
, was gleich ist mit [-2 31 , 2 31 -1].
Also für den Ausdruck x+1 > x
ist wahr für [-2147483648, 2147483646]
Aber nicht für 2147483647
, da das Hinzufügen zu 2147483647
in der 32-Bit-Größe Bit-Überlauf viele Implementierungen verursacht es macht x + 1
zu -2147483648
Aber wirklich Verhalten ist
Im C-Standard nicht definiert.
Also,
x + 1 > x
True für x
in [-2147483648, 2147483646]
only x + 1 > x
, für x = 2147483647
ist Undefinierter Wert kann True oder False sein, hängt vom Compiler ab. Wenn ein Compiler berechnet = -2147483648
Wert ist False. Ja, x + 1 addiert zum Dezimalwert von 1.
Das wird fast immer der Fall sein. Aber wenn Sie 1 zu INT_MAX hinzufügen (was 2 15 - 1 oder größer ist), könnten Sie das Zeichen umdrehen. Denken Sie an die Dezimaldarstellung von 0111111
gegenüber 11111111
. (Offensichtlich nicht 32 Bits, aber die Ideen halten.)
Sehen Sie sich das Zweierkomplement an, wenn Sie verwirrt sind, warum es umkippt. Es ist eine ziemlich clevere Implementierung von Ganzzahlen, die den Zusatz einfach macht.
EDIT: INT_MAX + 1
ist undefiniertes Verhalten. Wird nicht notwendigerweise INT_MIN
. Aber da x + 1
nicht unbedingt > x
ist, wenn x == INT_MAX
, dann ist die Antwort eindeutig falsch!
Tags und Links c