J'ai tendance à ajouter beaucoup d'assertions à mon code C ++ pour faciliter le débogage sans affecter les performances des versions de version. Maintenant, assert
est une macro C pure conçue sans mécanismes C ++ à l'esprit.
C ++ d'autre part définit std::logic_error
, qui est censé être levé dans les cas où il y a une erreur dans la logique du programme (d'où le nom). Lancer une instance pourrait bien être l'alternative parfaite, plus C ++ assert
.
Le problème est que , assert
et à la abort
fois mettre fin au programme immédiatement sans appeler Destructeurs, sauter donc le nettoyage, alors lancer une exception ajoute manuellement les coûts d'exécution inutiles. Une façon de contourner cela serait de créer une propre macro d'assertion SAFE_ASSERT
, qui fonctionne exactement comme l'homologue C, mais lève une exception en cas d'échec.
Je peux penser à trois opinions sur ce problème:
- Tenez-vous en à l'affirmation de C. Étant donné que le programme se termine immédiatement, peu importe que les modifications soient correctement déroulées. De plus, l'utilisation de
#define
s en C ++ est tout aussi mauvaise. - Lancez une exception et attrapez-la dans main () . Autoriser le code à ignorer les destructeurs dans n'importe quel état du programme est une mauvaise pratique et doit être évité à tout prix, tout comme les appels à terminate (). Si des exceptions sont lancées, elles doivent être interceptées.
- Lancez une exception et laissez-le terminer le programme. Une exception mettant fin à un programme est acceptable, et à cause de
NDEBUG
cela, cela ne se produira jamais dans une version de version. La capture est inutile et expose les détails d'implémentation du code interne àmain()
.
Y a-t-il une réponse définitive à ce problème? Une référence professionnelle?
Modifié: sauter les destructeurs n'est, bien sûr, pas un comportement indéfini.
logic_error
c'est l'erreur logique. Une erreur dans la logique du programme est appelée un bogue. Vous ne résolvez pas les bogues en lançant des exceptions.