Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1858 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  pourquoi faut-il bannir std::exit | bloc try-catch fonctionnel

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

pourquoi faut-il bannir std::exit | bloc try-catch fonctionnel

n°509611
Taz
bisounours-codeur
Posté le 07-09-2003 à 16:16:28  profilanswer
 

pré-requis :
 - connaître le mécanisme des exceptions
 - savoir comment créer ses propres exceptions
 - savoir attraper sainement une exception
 
 
    Je crois que j'en avais déjà parlé, mais je le formalise: pourquoi ne faut-il jamais, je dis bien jamais, utiliser std::exit (et les autres fonctions de sa famille). Une première bonne raison à mes yeux: elle vient du C, donc par définition, on va avoir des problèmes avec. Souvent quand on conçoit un programme, le traitement d'erreur implique des erreurs fatales (arrêt du programme), que l'on gère ça bien par exceptions, ou bien comme un cochon avec des codes d'erreurs ("Failure is not an error" d'ailleurs, si vous voulez une petite discussion sur les exceptions -> http://forum.hardware.fr/forum2.ph [...] 499&cat=10 , devenez adepte de la méthode EAFP fin de la ). Donc cette erreur fatale, vous la matérialisez par un appel à std::exit(). Malheureusement, c'est le coup de grâce. std::exit est une fonction bête qui va tuer votre programme d'un coup. Vous programmez bien avec une foultitude d'objets, bien, mais std::exit sans fiche bien, vos destructeurs ne seront __jamais__ appelés ... c'est vraiment un arrêt brutal, imaginez les conséquences si vous devez absolument relâcher certaines ressources (fichiers, verrous, connexions réseaux, matériel ...). l'horreur !
 
    Heureusement la solution est très simple dans le cas où cette erreur est inextrippable (impossible de retourner dans le main pour faire un joli return), il vous suffit de balancer une exception et de l'attendre. J'insiste bien sur le point « attendre » car le gestionnaire d'exceptions inattendues par défaut fera un appel à un truc genre _abort dont l'effet est le même que std::exit.
 
    Donc enserrer votre main dans un joli bloc try et placer 2 bloc catch: le premier pour std::exception, c'est à dire pour ramasser tout ce que vous lancer (intentionnellement ou pas) et un deuxième catch(...) pour rammasser le reste. Le mécanisme des exceptions assurant la destruction des objets, nous voilà hors de danger, tout est propre et sur, les erreurs sont maitrisées.
 
    Notez une synthaxe un peu inhabituelle dans l'exemple: le bloc try fonctionnel, c'est à dire pour enserrer une fonction (ou bien un constructeur, c'est là une autre discussion). c'est juste un exemple, je ferais sans doute un article sur cette construction, sachez qu'elle existe.
 
c++ exit.cpp -> gestion avec std::exit
c++ -DHFR_EXCEPTION exit.cpp -> gestion avec exception
 
comptez bien les instances zombies
 

Code :
  1. #include <iostream>
  2. #ifdef HFR_EXCEPTION
  3. #include <stdexcept>
  4. #endif
  5. // attention à tous ce qui commence par un C
  6. #include <cstdlib>
  7. using namespace std;
  8. // une classe avec un compteur
  9. // pour savoir qui est qui
  10. class Foo
  11. {
  12.   static int compteur;
  13.   int id;
  14. public:
  15.   Foo()
  16.     : id(++compteur)
  17.   {
  18.     cout << "Foo() " << id << '\n';
  19.   }
  20.   Foo(const Foo & )
  21.     : id(++compteur)
  22.   {
  23.     cout << "Foo(const Foo & ) " << id << '\n';
  24.   }
  25.   ~Foo()
  26.   {
  27.     cout << "~Foo() " << id << '\n';
  28.   }
  29. };
  30. int Foo::compteur=0;
  31. // une fonction où se produit une erreur fatale
  32. void Aurevoir(Foo b)
  33. {
  34.   Foo local(b);
  35.   Foo();
  36.   // soudain c'est le drame
  37. #ifndef HFR_EXCEPTION
  38.   exit(0);
  39. #else
  40.   throw logic_error("Boom !" );
  41. #endif
  42. }
  43. int main()
  44. try
  45. {
  46.   Foo a;
  47.   Foo(); // temporaire
  48.   Aurevoir(a);
  49. }
  50. catch(const exception &ex)
  51.   cerr << ex.what() << endl;
  52. }
  53. catch(...)
  54. {
  55.   cerr << "Unknown exception !" << endl;
  56. }


 
 
remarquez que cette méthode (enchasser le main avec 1 try / 2 catch) est la marque de bons logiciels.


Message édité par Taz le 21-10-2004 à 11:29:55
mood
Publicité
Posté le 07-09-2003 à 16:16:28  profilanswer
 

n°509760
blackgodde​ss
vive le troll !
Posté le 07-09-2003 à 22:32:21  profilanswer
 

ah, cool :) j'avais dejà un peu pensé à un truc comme ca, vu mon niveau chui fier de moi :p


---------------
-( BlackGoddess )-
n°509764
Taz
bisounours-codeur
Posté le 07-09-2003 à 22:36:11  profilanswer
 

BlackGoddess a écrit :

ah, cool :) j'avais dejà un peu pensé à un truc comme ca, vu mon niveau chui fier de moi :p

merde, t'es un mec  :sweat:

n°509767
blackgodde​ss
vive le troll !
Posté le 07-09-2003 à 22:38:05  profilanswer
 

oui, il est vrai que mon pseudo peut prêter a confusion ...


---------------
-( BlackGoddess )-
n°509783
schnapsman​n
Zaford Beeblefect
Posté le 07-09-2003 à 22:48:51  profilanswer
 

BlackGoddess a écrit :

oui, il est vrai que mon pseudo peut prêter a confusion ...


 
dommage pour toi, maintenant on ne te repondra plus  :lol:

n°509957
blackgodde​ss
vive le troll !
Posté le 08-09-2003 à 09:27:31  profilanswer
 

muh  :cry:  
si j'avais su j'aurais écrit fière :p


---------------
-( BlackGoddess )-
n°509970
LeGreg
Posté le 08-09-2003 à 10:03:32  profilanswer
 

sauf quand tu programmes des drivers.
 
Mais bon faire exit() c'est pas une bonne idée dans ce cas la non plus :D.
 
LeGreg

n°878541
xterminhat​e
Si vis pacem, para bellum.
Posté le 20-10-2004 à 23:10:29  profilanswer
 

Est-ce qu'un segfault déclenche catch(...) ?


---------------
Cordialement, Xterm-in'Hate...
n°878551
Taz
bisounours-codeur
Posté le 20-10-2004 à 23:34:16  profilanswer
 

non, un segfault, c'est un signal venant du noyau. En cas de segfault, le mieux est de ne rien faire. Si ça segfault, c'est que tu as corrompu ton espace mémoire : aucune contrainte n'est plus assurée, tu ne peux rien faire avec certitude. Alors autant arrêter les dégats.

n°878555
xterminhat​e
Si vis pacem, para bellum.
Posté le 20-10-2004 à 23:42:15  profilanswer
 

Effectivement, on peut rediriger le signal segfault mais l'execution est compromise.
 
Lorsque plusieurs bloques try-catch sont encapsulé, tu conseilles de manière générale de relancer le gestionnaire d'exception avec un throw dans les blocks catch ? ... histoire de retourner jusque dans le block catch de plus haut niveau, celui du main().


---------------
Cordialement, Xterm-in'Hate...
mood
Publicité
Posté le 20-10-2004 à 23:42:15  profilanswer
 

n°878556
xterminhat​e
Si vis pacem, para bellum.
Posté le 20-10-2004 à 23:46:50  profilanswer
 

Taz a écrit :

non, un segfault, c'est un signal venant du noyau. En cas de segfault, le mieux est de ne rien faire. Si ça segfault, c'est que tu as corrompu ton espace mémoire : aucune contrainte n'est plus assurée, tu ne peux rien faire avec certitude. Alors autant arrêter les dégats.


 
Si je redirige le signal correspondant au segfault vers une simple routine qui appel throw. Est-ce le block catch de la fonction en cours d'execution va s'executer ? Je sais, c'est tordu...


---------------
Cordialement, Xterm-in'Hate...
n°878557
Taz
bisounours-codeur
Posté le 20-10-2004 à 23:47:19  profilanswer
 

je comprends pas ta question. Si tu fais un catch, ne catch que ce que tu sais traiter. Tu peux également avoir des catch qui lance une nouvelle exception afin de préciser celle-ci (ou de lui donner un sens dans le contexte appelant).

n°878558
xterminhat​e
Si vis pacem, para bellum.
Posté le 20-10-2004 à 23:51:06  profilanswer
 

En somme ma question etait, est ce qu'on peut généraliser ton conseil (un double bloque try-catch dans le main) à toutes les fonctions et fonctions membres ? Y compris lorsqu'on ne sait pas traiter l'exception (tanpis, cela permet qd meme de la localiser finement).


---------------
Cordialement, Xterm-in'Hate...
n°878569
Taz
bisounours-codeur
Posté le 21-10-2004 à 00:05:20  profilanswer
 

ben non. Ça te sert à quoi d'attraper des exceptions dont tu n'a rien à faire ?

n°878585
xterminhat​e
Si vis pacem, para bellum.
Posté le 21-10-2004 à 00:19:39  profilanswer
 

A peu de chose. Principalement à la localiser.


Message édité par xterminhate le 21-10-2004 à 00:19:59

---------------
Cordialement, Xterm-in'Hate...
n°878590
Taz
bisounours-codeur
Posté le 21-10-2004 à 00:26:57  profilanswer
 

Ce n'est pas comme ça qu'il faudrait faire. y a pas de mécanisme de stacktrace en C++. tu veux t'aider avec __FILE__ et ses potes. La vrai question toute façon, c'est à quoi sert de localiser précisément une exception, à part afficher un message bien imbittable à l'utilisateur (n'est-ce pas Java ?).  Si tu peux traiter une exception, attrape là, et résous le problème si. Sinon, ne fais rien. Souviens toi que le code que tu manipules peux lancer n'importe quoi (surtout avec les templates). Ne présume de rien.

n°878795
Lam's
Profil: bas.
Posté le 21-10-2004 à 12:23:12  profilanswer
 

Bon, déjà, Sous Windows, un segfault lance une exception rattrapable avec catch (...)
 
D'autre part, les stack-traces, c'est vraiment très très pratique lorsque tu as des merdes sur un projet énorme à l'autre bout du monde et qui tourne depuis des jours: ça te permet de voir où ça merde, éventuellement pourquoi, sans avoir à retrouver la combinaison qui l'a fait planter.
 
Bref, dans ma boite on avait carrément implémenté le méchanisme permettant de les récupérer (soit on récupère le signal, et on exécute pstack sur le programme, soit on rajoute des infos de contexte qui créent une stack-trace virtuelle).  
 
Et l'utilisateur, il est content, parce qu'il n'a pas besoin d'écrire sur un bout de papier tout ce qu'il fait pour déclencher le crash, et parce qu'il a son diagnostic plus rapidement...
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  pourquoi faut-il bannir std::exit | bloc try-catch fonctionnel

 

Sujets relatifs
Comment afficher en 1 coup un bloc de pixels à l'écran?Recommencer un try tant que le catch s'active
Mieux que le bloc-notes[VISUAL C++ 6]Probleme de try .. catch
[C, C++] Equivalent C++ du "exit" en CExpression: BLOC_TYPE_IS_VALIDE????
[PHP] Bannir et nick List par cookies?[Tomcat] y'a moyen de sortir le traitement des jsp du bloc try catch ?
textarea ds bloc div ... (suite) 
Plus de sujets relatifs à : pourquoi faut-il bannir std::exit | bloc try-catch fonctionnel


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR