Ich neige dazu, meinem C ++ - Code viele Zusicherungen hinzuzufügen, um das Debuggen zu vereinfachen, ohne die Leistung von Release-Builds zu beeinträchtigen. Jetzt assert
handelt es sich um ein reines C-Makro, das ohne Berücksichtigung von C ++ - Mechanismen entwickelt wurde.
C ++ definiert dagegen std::logic_error
, was in Fällen ausgelöst werden soll, in denen ein Fehler in der Programmlogik vorliegt (daher der Name). Das Auslösen einer Instanz ist möglicherweise die perfekte Alternative zu C ++ assert
.
Das Problem ist , dass assert
und abort
sowohl das Programm sofort beenden , ohne Destruktoren aufrufen, damit die Bereinigung übersprungen, während eine Ausnahme werfen manuell fügt unnötige Laufzeitkosten. Eine Möglichkeit, dies zu umgehen, besteht darin, ein eigenes Assertionsmakro zu erstellen SAFE_ASSERT
, das genau wie das C-Gegenstück funktioniert, jedoch bei einem Fehler eine Ausnahme auslöst.
Ich kann mir drei Meinungen zu diesem Problem vorstellen:
- Halten Sie sich an Cs Behauptung. Da das Programm sofort beendet wird, spielt es keine Rolle, ob Änderungen korrekt abgewickelt werden. Ebenso
#define
schlecht ist die Verwendung von s in C ++. - Wirf eine Ausnahme und fange sie in main () ab . Das Überspringen von Destruktoren durch Code in einem beliebigen Status des Programms ist eine schlechte Praxis und muss unter allen Umständen vermieden werden, ebenso wie Aufrufe zum Beenden (). Wenn Ausnahmen ausgelöst werden, müssen sie abgefangen werden.
- Wirf eine Ausnahme und lass sie das Programm beenden. Eine Ausnahme beim Beenden eines Programms ist in Ordnung, und aufgrund
NDEBUG
dessen wird dies in einem Release-Build niemals passieren. Das Abfangen ist nicht erforderlich und macht Implementierungsdetails des internen Codes verfügbarmain()
.
Gibt es eine endgültige Antwort auf dieses Problem? Irgendeine professionelle Referenz?
Bearbeitet: Das Überspringen von Destruktoren ist natürlich kein undefiniertes Verhalten.
static_assert
wo es angebracht ist, wenn Sie dies zur Verfügung haben.
std::bug
?
std::abort()
. Es wird nur ein Signal ausgelöst, das den Prozess beendet.
logic_error
ist der logische Fehler. Ein Fehler in der Programmlogik wird als Fehler bezeichnet. Sie lösen Fehler nicht, indem Sie Ausnahmen auslösen.