für jedes int x: x + 1 x ... ist das immer wahr?

8

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?

    
gormandy 05.07.2013, 20:49
quelle

4 Antworten

25
%Vor%

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).

    
ouah 05.07.2013, 20:52
quelle
4

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.
Grijesh Chauhan 05.07.2013 20:58
quelle
2

Ich möchte Ihnen die Antwort nicht geben, also werde ich mit einer Frage antworten, die Sie auf den richtigen Weg bringen sollte.

Was ist x + 1 , wenn x der größtmögliche Wert ist, der in einer 32-Bit-Ganzzahl mit Vorzeichen gespeichert werden kann? (2 147 483 647)

    
cdhowie 05.07.2013 20:52
quelle
-1

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!

    
vroomfondel 05.07.2013 20:54
quelle

Tags und Links