Ich hoffe, dieser Thread ist immernoch für Brainstorming da … mir fiel beim
jammern ein:
Man kann Assertions nicht nur zum Debugging nutzen, sondern auch für Optimierungen – dafür #definiert man Assertions in Debug-Builds nicht leer, sondern (unter Visual C++) mit
__assume(expr). Während man im Debug-Build also sagt:
Diese Bedingung muss eintreten, und falls nicht, brich die Ausführung ab, damit ich korrigieren kann, bedeutet es in Release-Builds:
Diese Bedingung muss eintreten, optimier daraufhin.
Bei mir bringt das ordentlich was, weil ich z.B. bei Funktionen, die allokierte Objekte zurückgeben
müssen,
assert(nullptr != result); vor den
return-Ausdruck schreibe. Der Compiler weiß dann im weiteren Verlauf, dass das Ergebnis der Funktion und alle Zeiger, in denen es gespeichert wurde, nicht
nullptr sein kann und optimiert jeden Text, der etwas anderes annehmen könnte oder Rückgabewerte testet, weg. Das schmeißt nochmal vieles raus, was LTCG nicht von allein rafft (wenn auch imo nicht genug). Wenn man
assert() hingegen leer #definiert, bleiben diese Optimierungen aus.
Viel bringt das auch, wenn man per
assert() Wertebereiche von Variablen festlegt.
Visual C++ kann nur einfache Ausdrücke, wie Vergleiche, verwerten. Sowas wie
assert(0xFCBDA == computeCRC32of(mesh.header()->id())) würde ignoriert und nicht zur Optimierung herangezogen; würde es bei leerem Release-
assert() aber ebenso.
Ihr könnt also mal darüber nachdenken, ob ihr
ai_assert() in Release-Builds unter Visual C++ nicht zu
#define ai_assert(expression) __assume(expression) ändert. Ich habe leider momentan kein Assimp-abhängiges Projekt, sonst hätte ich selber schon getestet, wie viel das bringen würde (wenn überhaupt – es hängt eben auch davon ab, wie oft und wie komplex man
ai_assert() einsetzt). Aber ich glaube zumindest nicht, dass es schaden könnte.
Nachtrag: Gerade ausprobiert; 8 KiB bzw. 0,5 % weniger Maschinentext. Nicht viel, aber wenn man die beiden Speicherseiten schonmal fast gratis bekommt, kann man sie auch direkt mitnehmen.