On m'a déjà dit qu'un programme C ++ devrait finalement intercepter toutes les exceptions. Le raisonnement donné à l'époque était essentiellement que les programmes qui permettent aux exceptions de se propager en dehors d' main()
entrer dans un état de zombie étrange. On me l'a dit il y a plusieurs années et, rétrospectivement, je crois que le phénomène observé était dû à la longue génération de décharges de noyau exceptionnellement grandes à partir du projet en question.
À l'époque, cela semblait bizarre mais convaincant. Il était totalement insensé que C ++ "punisse" les programmeurs pour ne pas avoir intercepté toutes les exceptions, mais les preuves dont je disposais semblaient corroborer cela. Pour le projet en question, les programmes qui ont levé des exceptions non capturées semblaient entrer dans un état de zombie étrange - ou comme je soupçonne que la cause était maintenant, un processus au milieu d'un vidage de mémoire indésirable est exceptionnellement difficile à arrêter.
(Pour quiconque se demande pourquoi cela n'était pas plus évident à l'époque: le projet a généré une grande quantité de sortie dans plusieurs fichiers à partir de plusieurs processus qui ont effectivement masqué toute sorte de aborted (core dumped)
message et dans ce cas particulier, l'examen post mortem des vidages de mémoire n'a pas été Ce n'est pas une technique de débogage importante, donc les vidages de mémoire n'ont pas été beaucoup réfléchis. Les problèmes avec un programme ne dépendent généralement pas de l'état accumulé à partir de nombreux événements au fil du temps par un programme de longue durée, mais plutôt des entrées initiales d'un programme de courte durée (< 1 heure), il était donc plus pratique de simplement réexécuter un programme avec les mêmes entrées à partir d'une version de débogage ou dans un débogueur pour obtenir plus d'informations.)
Actuellement, je ne sais pas s'il y a un avantage ou un inconvénient majeur à intercepter des exceptions uniquement dans le but d'empêcher les exceptions de quitter main()
.
Le petit avantage main()
auquel je peux penser pour permettre aux exceptions de se propager dans le passé est qu'il provoque l' std::exception::what()
impression du résultat sur le terminal (au moins avec les programmes compilés par gcc sous Linux). D'un autre côté, cela est trivial à réaliser en capturant à la place toutes les exceptions dérivées de std::exception
et en imprimant le résultat de std::exception::what()
et s'il est souhaitable d'imprimer un message à partir d'une exception qui ne dérive pas, std::exception
il doit être capturé avant de quitter main()
afin d'imprimer le message.
Le désavantage modeste auquel je peux penser pour permettre aux exceptions de remonter dans le passé main()
est que des vidages de mémoire indésirables peuvent être générés. Pour un processus utilisant une grande quantité de mémoire, cela peut être assez gênant et le contrôle du comportement de vidage du noyau à partir d'un programme nécessite des appels de fonction spécifiques au système d'exploitation. D'un autre côté, si un vidage de mémoire et une sortie sont souhaités, cela peut être réalisé à tout moment en appelant std::abort()
et une sortie sans vidage de mémoire peut être obtenue à tout moment en appelant std::exit()
.
Pour l'anecdote, je ne pense pas avoir jamais vu le what(): ...
message par défaut imprimé par un programme largement distribué lors du plantage.
Quels sont, le cas échéant, les arguments solides pour ou contre l’autorisation de voir les exceptions C ++ se multiplier main()
?
Edit: Il y a beaucoup de questions générales sur la gestion des exceptions sur ce site. Ma question concerne spécifiquement les exceptions C ++ qui ne peuvent pas être gérées et qui ont réussi jusqu'à main()
- peut-être qu'un message d'erreur peut être imprimé mais c'est une erreur d'arrêt immédiat.