the compiler never promised what you assumed
man signed-overflow
UNDEFINED. Nicht falsch, nicht abgefangen, nicht auf einen Wert festgelegt. Eine Lizenz für den Compiler, Code schneller zu machen, auf Kosten davon, dass er tut, was du erwartest.
gdb loop.bin
Schleife zählt bis zum int-Grenzwert. Compiler nimmt an: Overflow passiert laut Spec nie. Optimiert die Abbruchbedingung weg. Ergebnis: keine falsche Zahl. Eine Endlosschleife, die im Quellcode gar nicht so aussieht.
grep -r "premise" compiler/
Wer undefined behavior debuggt, sucht meist am falschen Ort. Die Berechnung ist oft korrekt, gegeben die Prämisse: dass dein Code nie UB auslöst. Wird sie verletzt, ist alles danach formal beliebig, nicht nur eine Zeile.
grep -r "not just C" notes/
Dieselbe Struktur überall, wo eine Spezifikation einen Fall offen lässt, weil er unwahrscheinlich schien: Vertrag, Protokoll, Gesetzestext. Nur ohne Compiler, der es dir vorher um die Ohren haut.
Der Compiler lügt nicht. Er nimmt dich beim Wort, und dein Wort war ungenauer, als du dachtest.
Interne Notiz, Compiler-Team