Ursprünglich stellten die meisten Formen von Undefined Behavior Dinge dar, die bei einigen Implementierungen auftreten können, bei anderen Implementierungen jedoch nicht. Weil es für die Autoren des Standards keine Möglichkeit gab, alle Dinge vorherzusagen, die eine Plattform im Falle einer Falle machen könnte (einschließlich buchstäblich der Möglichkeit, dass ein System einen Alarm ausgibt und blockiert, bis ein Bediener den Fehler manuell löschte) , die Folgen von Fallen fielen nicht in den Zuständigkeitsbereich des C-Standards, und somit wird fast jede Aktion, für die eine Plattform möglicherweise eine Falle verursachen könnte, aus der Sicht des Standards als "Undefiniertes Verhalten" betrachtet.
Das sollte nicht bedeuten, dass die Autoren des Standards nicht glauben, dass Implementierungen versuchen sollten, sich vernünftig für solche Dinge zu verhalten, wenn sie praktikabel sind.Die Autoren der C89 Norm erwähnt, zum Beispiel, dass die Mehrzahl der aktuellen Systeme dieser Ära Verhalten definieren würde:
/* Assume USmall is half the size of "int" */
unsigned mult(USmall x, USmall y) { return x*y; }
die in allen Fällen würde, einschließlich solche, bei denen das mathematische Produkt von x und y war zwischen INT_MAX + 1 und UINT_MAX, entspricht (unsigned)x*y;
. Ich sehe keinen Grund zu glauben, dass sie nicht erwartet hätten, dass sich dieser Trend fortsetzt.
Leider ist eine neue Philosophie in Mode gekommen, basierend auf dem revisionistischen Standpunkt, dass Compiler-Autoren nur hilfreiche Verhaltensweisen in Fällen unterstützt haben, die nicht vom Standard vorgeschrieben sind, weil sie zu einfach waren, um etwas anderes zu tun. In gcc, zum Beispiel, unter Verwendung der Optimierungsstufe 2, aber keiner anderen Nicht-Standardoptionen, erzeugt die obige "mult" -Routine manchmal falschen Code in Fällen, in denen das Produkt zwischen 0x80000000u und 0xFFFFFFFFu liegen würde, selbst wenn es auf Plattformen läuft, wo solche Berechnungen stattfinden würden historisch haben gearbeitet. Dies geschieht angeblich im Namen von "Optimierung"; Es wäre interessant zu wissen, wie viele der "Optimierungen", die solche Techniken durchführen, tatsächlich nützlich sind und nicht mit sichereren Mitteln hätten erreicht werden können.
Historisch war Undefined Behavior eine Lizenz für einen C-Compiler, um das Verhalten der zugrunde liegenden Plattform offenzulegen. In Fällen, in denen das Verhalten der zugrundeliegenden Plattform den Bedürfnissen des Programmierers entsprach, konnten die Anforderungen des Programmierers effizienter in Maschinencode ausgedrückt werden, als wenn alles auf eine vom Standard definierte Weise ausgeführt werden müsste. In letzter Zeit wurde es jedoch als Lizenz für Compiler interpretiert, um Verhaltensweisen zu implementieren, die nicht nur nichts mit der zugrundeliegenden Plattform zu tun haben, noch irgendwelche plausiblen Programmierererwartungen, aber nicht einmal an Gesetze von Zeit und Kausalität gebunden sind.
Sie meinen, neben dem offensichtlichen Grund? –
Es gibt eine Leistungseinbuße durch Überprüfung der Grenzen jedes einzelnen Array-Zugriffs. –
weil es ziemlich schwierig ist, es zumindest in der Vergangenheit und jetzt zu verbieten. – user3528438