Ganzzahlüberlauf auf x86 mit GCC, der eine Endlosschleife verursacht
Einführung
Im folgenden Codeausschnitt Ganzzahl Ein Überlauf auf x86 mit GCC führt unerwartet zu einer Endlosschleife anstelle des erwarteten Umbruchs Verhalten:
int i = 0x10000000; do { i += i; } while (i > 0);
Analyse
Ganzzahlarithmetik auf x86-CPUs folgt typischerweise dem Umlaufverhalten der Zweierkomplementdarstellung. Im oben genannten Code führt der vorzeichenbehaftete Ganzzahlüberlauf jedoch dazu, dass das Programm in eine Endlosschleife eintritt.
Das Problem
Das undefinierte Verhalten des vorzeichenbehafteten Ganzzahlüberlaufs führt zu unvorhersehbaren Ergebnissen auf x86 . GCC geht davon aus, dass Ganzzahlen nicht überlaufen, und optimiert den Schleifentest weg. Infolgedessen wird die Schleife auf unbestimmte Zeit fortgesetzt.
Beobachtungen
Erklärung
Wenn ein Ganzzahlüberlauf auftritt, werden die Statusflags der CPU nicht aktualisiert. Unter der Annahme, dass kein Überlauf vorliegt, überprüft der Compiler die Flags nicht und fährt mit der Schleife fort, was zu einer Endlosschleife führt.
Auflösung
Um das gewünschte Wraparound-Verhalten sicherzustellen, muss der Compiler Flag -fwrapv sollte verwendet werden. Dieses Flag ermöglicht eine wohldefinierte Integer-Überlaufsemantik, kann jedoch Auswirkungen auf die Leistung haben.
Fazit
Vorzeichenbehafteter Integer-Überlauf ist undefiniertes Verhalten und kann zu unvorhersehbaren Ergebnissen führen. Compiler optimieren möglicherweise auf der Grundlage der Annahme, dass es keinen Überlauf gibt, was zu unerwartetem Verhalten führt. Die Verwendung von -fwrapv kann ein Wraparound-Verhalten erzwingen, sollte jedoch gegen mögliche Auswirkungen auf die Leistung abgewogen werden.
Das obige ist der detaillierte Inhalt vonWarum verursacht ein vorzeichenbehafteter Ganzzahlüberlauf auf x86 mit GCC eine Endlosschleife?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!