Kontext: In diesem answer erfuhr ich, dass gcc __builtin_unreachable()
einige überraschend impactful Auswirkungen auf die Leistung haben kann, wie es, dass die folgende scheint:Gibt es einen Grund dafür, assert() nicht in ein Makro zu packen, das in gcc zu __builtin_unreachable() aufgelöst wird?
if(condition) __builtin_unreachable();
vollständig abgezogen wird, und als Optimierungshinweis solange condition
verwendet kann garantiert keine Nebenwirkung haben.
So meine erste Reaktion darauf ist, dass ich das folgende Makro erstellen sollte, und verwenden Sie es absolut überall würde ich normalerweise assert()
verwenden, da Nebeneffekt induziert Code innerhalb einer assert()
ein großer Fehler in erster Linie sein würde:
// TODO: add handling of other compilers as appropriate.
#if defined(__GNUC__) && defined(NDEBUG)
#define my_assert(condition) \
if(!(condition)) __builtin_unreachable()
#else
#define my_assert(condition) assert(condition)
#endif
aus Standards Perspektive, würde dies eine Spaltung in der Funktionalität zwischen normalen erstellen und NDEBUG
baut, mit dem Sie ein Argument dieses Makro schließt davon, dass das Standardverhalten von assert()
machen könnte. Da mein Code jedoch im Fall von Assertionsfehlern funktionell tot im Wasser ist, ist er vom Verhalten her gesehen völlig äquivalent.
Also meine Frage ist: Kann jemand einen Grund denken, dies nicht zu tun (appart aus behauptet, dass viele Umleitungen beinhalten)?
Bevor Sie fragen, ja, habe ich überprüft, dass gcc Verhalten ist, um die Behauptung weg in NDEBUG
Builds void.
Relevante https://stackoverflow.com/a/40447259/817643 – StoryTeller
Kein Grund, dies nicht zu tun, soweit ich das beurteilen kann. Sie nehmen etwas für die Optimierung in Release-Builds an und ersetzen es durch eine Assertion in Debug-Builds, um Programmierfehler zu erfassen. – StoryTeller
"Verwenden Sie es absolut überall" -Ansatz wird nicht wirklich funktionieren, weil Debug-Assertionen oft Variablen und Aufrufe enthalten, die nur im Debug-Modus verfügbar sind. Die bessere Idee wäre, ein dediziertes Makro mit einem passenderen Namen wie 'my_assume' zu definieren und es nur an geeigneten Stellen zu verwenden. – VTT