Fragen? Antworten! Siehe auch: Alternativlos
Mein ursprüngliches zentrales Anliegen in dem Vortrag war, den Programmierern die Illusion zu nehmen, dass sie schlauer als der Compiler sind. Später bin ich dann zu der Erkenntnis gelangt, dass das auch ein Sicherheitsproblem ist, wenn die Leute falsche Vorstellungen davon haben, welcher C-Code langsamen Maschinencode erzeugen wird und welcher nicht. Im Normalfall kosten z.B. Integer-Overflow-Checks gar nichts. Man muss sich anstrengen, um das überhaupt messen zu können. Das liegt daran, dass CPUs heutzutage superskalar sind, d.h. die funktionalen Einheiten ("Integer-Arithmetik" ist eine andere Einheit als "aus dem Speicher einen Wert laden") arbeiten unabhängig voneinander und asynchron. Und die CPUs sind heutzutage so viel schneller als der Arbeitsspeicher Werte liefern kann, dass die CPUs im Normalfall gerade auf irgendeinen Wert aus dem Hauptspeicher warten und die anderen Einheiten idle sind. Ob die jetzt einen Integer Overflow-Check machen, der im Normalfall eh nicht auslöst, das spielt keine Rolle.
Dennoch suchen Programmierer nach Ausreden, wieso irgendwas langsam sein könnte, daher habe ich in den Folien ab Seite 57 (nach Seitennummerierung der Folien) Overflow-Checks und den generierten Code angeschaut. Ich komme zu dem Ergebnis, dass Checks für Addition heute schon kostenlos sind, aber bei Multiplikation noch Optimierungspotential besteht. Ich meinte damals, dass die Compiler das fixen können, indem sie ihren Codegenerator verbessern, aber stattdessen haben die Compiler jetzt Intrinsics eingeführt. Zumindest clang und gcc ab Version 5.0. Hier ist das gcc 5 Neuerungen-Dokument, sucht darin mal nach __builtin_mul_overflow. Darin bewerben sie das Intrinsic genau damit, dass da nur noch ein mul mit einem jump on overflow rauskommt. Das ist genau was ich in meinen Folien als Ziel angesagt hatte damals.
Das möchte ich zum Anlass für die Ansage nehmen, dass es jetzt keinerlei Ausrede mehr gibt, nicht Integer Overflow-Checks zu machen. Das mul muss man eh machen, und jetzt kommt halt noch ein Jump dazu, der nie genommen wird, außer jemand exploitet den Code gerade. Der kostet nichts.
Macht mehr Overflow Checks!
Einen Vorteil hat die Intrinsic-Variante. Da können die Werte verschiedene Typen haben und der prüft auch gleich auf Truncation. Das spart schon Gefummel und Fehlerpotential gegenüber manueller Prüfung.