Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zér0 > Les tutoriels > Non-Officiels > Programmation > C++ > Lecture des commentaires

Vos commentaires sur :
[C++] La gestion des exceptions

Retour au tutoriel

Vous devez être inscrit pour pouvoir poster des messages

Page : 1 
Pseudo Commentaire
Page : 1 
Hors ligne Nanoc # Posté le 20/01/2008 20:01:07
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
Si vous avez des questions ou des remarques, n'hésitez pas !

Merci d'utiliser le forum si vous avez des questions techniques.
 
Hors ligne the angel # Posté le 20/01/2008 20:18:28
Avatar
Groupe : Membres
Salut, juste pour t'informer que tu as fait une petite erreur.

A la fin de la partie sur les exceptions tu explique pourquoi il faut utiliser les références :
Citation : Nanoc
Si l'on avait attrapé l'exception par valeur et pas par référence(c'est-à-dire sans le &), le message aurait été "std::exception", car le polymorphisme n'est pas conservé. C'est pour cela que l'on attrape toujours les exceptions par valeur.


Bon puisque je poste je te dis où est la faute, bien que tu l'ai peut-être déjà corriger en lisant la citation ^^. Donc le dernier mot est à remplacer par "référence".

Au revoir.
Hors ligne noob4ever # Posté le 20/01/2008 20:20:03
.NETeu boutoneu :)
Avatar
Groupe : Membres
hé moi qui me cassait la tête il y a 2 jours avec ça, voila que je trouve ce tuto ...

très bon travail !

20/20
 
Hors ligne SpaceFox # Posté le 20/01/2008 22:00:15
Ton code existe deja, en mieux
Avatar
Groupe : Membres
Deux questions/remarques :
1- le bout de code, écrit tel quel :
Code : C++ - Afficher / masquer les numéros de ligne
  1. catch(...)
  2. {
  3. }

avec les 3 points récupère vraiment toutes les exceptions ? C'est pas vraiment clair et assez surprenant.

2- Y'a pas d'équivalent au "finally" de Java en C++ ?

Sinon, le tuto est intéressant et clair.
Hors ligne Hiura # Posté le 20/01/2008 22:08:48
Avatar
Groupe : Membres
Salut.
J'ai beaucoup apprécié ce tuto! Il est vraiment complet et bien conçu. Bravo!

Mais ( :-° )
Citation : Un problème bien ennuyeux
que l'on pas allouée précédemment

devrait être
Citation : Un problème bien ennuyeux
que l'on a pas allouée précédemment


Je sais, je pinaille. :p

La concéption est vraiment bien, d'abord la théorie, puis la pratique ; explication de std::cerr ; très bien expliqué. (Et tout plein d'autres points.)

Citation : Tuto
Il ne faut jamais lever d'exception dans un destructeur. Une des raisons est la suivante: Que faire si la destruction d'un objet rate ? Cette question n'a pas de réponse satisfaisante.

Cela signifie qu'il en existe une ; qu'elle est-elle (juste pour info)?

J'ai encore une question : std::runtime_error? (et ses soeurs).
Tu n'en parles pas ; as-tu des infos sur ces execptions? Je me demandais à quoi elles servent au niveau de la concéption.

Merci pour la rédaction de ce tuto fort utile!
(19/20)
 
Hors ligne Cyprien_ # Posté le 21/01/2008 08:22:17
Le Monde d'Akhiris
Avatar
Groupe : Membres
Deux autres petites erreurs :

Citation : Nanoc
Si une exception est levée dans un constructeur, le destructeur n'est pas appelé, il faut donc libérer la mémoire allouée via des new dans le catch.


Pour libérer la mémoire, j'utilise rarement des new :p .

Pour la 2e, je ne suis absolument pas certain, mais je demande au moins confirmation :

Citation : Nanoc
void fonction3() throw(); //Une fonction qui ne lance rien.

void fonction4(); //Une fonction qui peut lancer n'importe quel type d'exception.


C'est pas l'inverse par hasard ? Ca me semble bizarre qu'une fonction suivie de throw() ne lance rien o_O .

A part ça, enfin un tuto compréhensible sur les exceptions ! Merci beaucoup Nanoc !
Rien que pour ça, je mets 19/20 ^^ .

EDIT : ok, merci pour la confirmation ;) .

Un jeu online novateur ?
Le Monde d'Akhiris !
 
Hors ligne Nanoc # Posté le 21/01/2008 08:53:28
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
Merci pour vos remarques, j'ai corrigé.

@hiura: Concernant la levée d'exceptions dans un destructeur, j'ai volontairement omis la réponse complexe. Le problème principal n'est pas que l'on sait pas quoi faire (bien que ...) mais plutôt le suivant:
Imaginons que dans une fonction a, je crée une instance de B. Puis toujours dans cette fonction une exception est levée. Le programme va alors détruire tous les objets déclarés dans a pour remonter jusqu'au bloc catch (dans le main par exemple). Malheureusement, la destruction de B se passe mal. On se retrouve alors avec 2 exceptions à traiter. Ce qui est impossible !
Pour plus de détails, regarde la FAQ de developpez.com

@Cyprien_ : C'est correct, si l'on indique rien, la fonction peut lancer n'importe quoi. Il est plus important d'indiquer qu'une fonction est "exception-safe" que d'indiquer qu'une fonction peut lancer n'importe quoi.
 
Hors ligne Hiura # Posté le 21/01/2008 16:54:19
Avatar
Groupe : Membres
Merci bien pour cette explication claire!
 
En ligne Davidbrcz # Posté le 21/01/2008 17:48:29
Geek un jours, geek toujours !
Avatar
Groupe : Membres
Et le RAII pour éviter les merdes avec la mémoire alloué dynamiquement ?

Partager grâce à l'open source et aux logiciels libres.

Mes articles dur developpez.com : http://come-david.developpez.com/

Da Nyug
 
Hors ligne akhenathon # Posté le 21/01/2008 18:38:11
euh...
Avatar
Groupe : Membres
vraiment très bon tuto sur un point de la programmation très important

seulement j'aimerais dire un petit truc qui m'a choqué

tu dis:

Citation : Nanoc
Il est en particulier impossible de réaliser le calcul {a}/(b / c) en une seule ligne.


or c'est un très mauvais exemple tout simplement parce que c'est faux

je ne connais pas ton niveau en math mais je pense que tu sais que
\frac{a}{\frac{b}{c}} = a * \frac{c}{b} = \frac{a*c}{b}

donc avec un simple:
Code : C++ - Afficher / masquer les numéros de ligne
  1. division(a*c,b);


on arrive à faire cette opération qui a l'air compliquée et en une seule ligne en plus

WTF :p
Code : SQL - Afficher / masquer les numéros de ligne
  1. DROP DATABASE IF EXISTS WTF
 
Hors ligne Xeroth # Posté le 21/01/2008 18:45:17
Vive les petits pois !
Avatar
Groupe : Membres
Très bon tuto, ça va beaucoup m'aider :)
Merci (18/20)

Sinon a akhenathon :
Je pense que Nanoc veut dire qu'on ne peut pas faire :
Code : C++ - Afficher / masquer les numéros de ligne
  1. division(a,division(b,c));

Comme on pourrait le faire avec les deux premières solutions
Hors ligne Nanoc # Posté le 21/01/2008 21:04:28
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
@Davidbrcz : Cela me semble trop avancer pour être présenté dans un tutoriel pour débutant. Mais peut-être que je me trompe ?

@akhenaton: Effectivement, tu as raison. Mais ce n'est pas le but ici. Je voulais dire que l'on ne peut pas faire

division(a,division(b,c));
 
Hors ligne Kurlze # Posté le 21/01/2008 23:06:40
L.O.S.T
Avatar
Groupe : Membres
Bravo. J'avais déjà entendu parler de ces exceptions et déjà vu du code, mais le tuto est très bien expliqué. (Pour tout avouer, je ne m'en suis jamais servi encore, je n'en ai pas eu l'obligation)

Mais quelques questions :

¤ Ces exceptions ne sont-elles pas une sorte de goto ?


¤ Tu dis au début qu'une solution est mauvaise car elle ne renvoie aucune valeur (Alors que le type de retour est un int (ou bool)). Certes c'est vrai; mais avec les exceptions (en tout cas sur ton exemple) :

Code : C++ - Afficher / masquer les numéros de ligne
  1. int division(const int& a,const int& b) //Calcule a divisé par b
  2. {
  3.    if(b==0)
  4.       throw Erreur(1,"Division par zéro",2);
  5.    else
  6.       return a/b;
  7. }


Si on entre b = 0; on lève une exception avec throw : le programme retourne directement dans le main jusqu'au catch. Or la fonction n'a rien retourné théoriquement. Ce n'est pas un peu pareil qu'au début ?


¤ Pour ce prototype je n'ai bien pas compris non plus :

Code : C++ - Afficher / masquer les numéros de ligne
  1. void fonction3() throw();  //Une fonction qui ne lance rien.


Si on ajoute trow(), cela signifie que la fonction ne lance aucune exception ? Ou alors l'exception rattrape n'importe quel type d'objets ? Car quel est l'intêret d'ajouter throw() si "la fonction ne lance rien"


¤ L'exemple de la divison par zero n'est-il pas exagéré ? N'est-il pas plus lisible et plus simple de faire comme ceci :

Code : C++ - Afficher / masquer les numéros de ligne
  1. int main()
  2. {
  3.    int a,b;
  4.    std::cout << "Valeur pour a: "<< std::flush;
  5.    std::cin >> a;
  6.    std::cout << "Valeur pour b: "<< std::flush;
  7.    std::cin >> b;
  8.  
  9.    if (b == 0)
  10.        std::cerr << "Erreur : Division par zero" << std::endl;
  11.    else
  12.        std::cout << a << " / " << b << " = " << division(a,b) << std::endl;
  13.  
  14.    return 0;
  15. }


18

You cannot change your fate. No man can.
 
Hors ligne Nanoc # Posté le 22/01/2008 08:29:38
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
Merci d'utiliser le forum pour poser des questions. C'est plus pratique pour répondre.

Citation : Mercenary
Ces exceptions ne sont-elles pas une sorte de goto ?


Non. Les exceptions sont beaucoup mieux que les goto.
1) On peut lancer une exception dans une fonction et la rattraper ailleurs, impossible avec goto
2) On peut transmettre de l'info avec une exception pas avec un goto
3) Le goto rend le code "spaghetti", avec une exception, l'execution reprend directement après le catch et pas ailleurs.
4) Les exceptions appelent les destructeurs et détruisent les variables déclarées dans une fonction. Pas le goto.

de manière générale en C++: NE JAMAIS UTILISER GOTO.

Citation : Mercenary
Tu dis au début qu'une solution est mauvaise car elle ne renvoie aucune valeur (Alors que le type de retour est un int (ou bool)). Certes c'est vrai; mais avec les exceptions (en tout cas sur ton exemple).
Si on entre b = 0; on lève une exception avec throw : le programme retourne directement dans le main jusqu'au catch. Or la fonction n'a rien retourné théoriquement. Ce n'est pas un peu pareil qu'au début ?


Non, dans le cas de l'exception, la fonction ne se termine pas. Et le main ne reçoit aucune valeur. Il n'en attend d'ailleurs aucune puisque l'exécution reprend dans le catch et pas dans le main.

Citation : Mercenary
Si on ajoute trow(), cela signifie que la fonction ne lance aucune exception ? Ou alors l'exception rattrape n'importe quel type d'objets ? Car quel est l'intêret d'ajouter throw() si "la fonction ne lance rien"


Cela signifie, comme je l'ai dit, que la fonction ne lance rien. En d'autres mots, cela veut dire que cette fonction ne peut pas planter ! C'est hyper-intéressant comme informatio, non ? On est ainsi sûr que cette fonction marchera dans tous les cas. Cela permet aussi de savoir qu'on a pas besoin d'entourer l'appel de la fonction de blocs try...catch.

Citation : Mercenary
L'exemple de la divison par zero n'est-il pas exagéré ? N'est-il pas plus lisible et plus simple de faire comme ceci :

Evidemment en mettant tout dans le main... Mais c'est pas le but de l'exemple. Il fallait bien que je prenne un exemple simple.

Merci à toi.
 
Hors ligne Magorath # Posté le 22/01/2008 08:39:19
Groupe : Membres
Excellent tutoriel. Je trouve que tu aurais juste pu donner un peu plus d'informations sur std::cerr.

Magorath
 
Hors ligne shadosan # Posté le 23/01/2008 18:03:10
And a new day will dawn...
Avatar
Groupe : Membres
Très bien fait ! Je trouvais aussi qu'il manquait un tuto sur les exceptions ^^

20!

Une petite question par contre (par curiosité) : qu'est-ce que la licence "creative commons" attribué au tuto fait/permet/oblige/empêche?
 
Hors ligne Nanoc # Posté le 23/01/2008 18:11:31
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
http://creativecommons.org/licenses/by-sa/2.0/fr/
 
Hors ligne shadosan # Posté le 23/01/2008 22:48:28
And a new day will dawn...
Avatar
Groupe : Membres
ah oui, j'suis un boulet, il y avais même un lien sur l'image -_-; désolé :p
 
Hors ligne Magorath # Posté le 25/01/2008 09:27:30
Groupe : Membres
J'ai juste une petite question, à quoi peut servir de changer la fonction std::terminate ?

Magorath
 
Hors ligne gusgus # Posté le 25/01/2008 14:57:16
Avatar
Groupe : Membres
Géniale se tuto!

tutos Moteur 3d(Ogre)/Moteur Physique(PhysX): http://easy3dgames.tuxfamily.org
 
Hors ligne Chlab_lak # Posté le 26/01/2008 20:02:26
Avatar
Groupe : Membres
tu as oublier:
- l'exception std::out_of_range dans les exceptions levées par la SL
- std::logic_error qui derive de std::exception ainsi que ses soeurs

sinon tres bon tuto
 
Hors ligne Nanoc # Posté le 26/01/2008 21:48:07
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
@Magorath:
Cela peut servi pour détruire quelques objets "en catastrophe" mais normalement on a jamais besoin de la changer.

@Chlab_lak:
LEs 2 exceptions que tu citent dérivent bien de std::exception. Elles ne font par contre pas partie de la SL mais de la STL. Or dans la STL, il y a énormément d'autres types d'erreurs qui peuvent être lancées. J'ai donc préféré mettre aucune exception de la STL et me limiter aux 5 de la SL.
 
Hors ligne kaysersose # Posté le 08/02/2008 13:48:01
Groupe : Membres
Bonjour!

Ceci est mon premier post après plusieurs lectures de différents tutoriels (en particulier ceux sur le C/C++).
Je tenais à dire que c'est un très bon tutoriel sur la gestion des exceptions que tu as réalisé. Je l'ai trouvé clair et facile à comprendre en comparaison avec certains ouvrages.

Je lui mets 20/20.

Merci
Hors ligne geenux # Posté le 19/02/2008 22:01:44
Vive Qt
Avatar
Groupe : Membres
Dans mes 2 livres de c++, en plusieurs mois je n'avais pas réussi à comprendre le but des exception et là, en 1/2 heure j'ai tout compris!

Secret (cliquez pour afficher)
19.99/20 (j'ai mis 20 dans la note)

Signez la pétition pour M6 Replay accessible à tous, sans exception ! M6 déclare "Accessible à tous", sous entendu Tous les utilisateurs de Windows© disposant du lecteur Windows media. Donc ils excluent volontairement les utilisateurs de systèmes comme GNU/Linux ou Mac OS, en faisant de la publicité "mensongère".
 
Hors ligne lmghs # Posté le 09/03/2008 01:42:46
Groupe : Membres
Diverses petites remarques.

a- Prendre des int, en argument, par référence-constante n'a qu'un seul intérêt: sous-entendre qu'ils pourraient être plusieurs dans un tableau, ou qu'un truc à l'extérieur pourrait les modifier. Il n'y a guère qu'à partir de deux int que l'on commence à percevoir une différence.

b- Mieux que le catch par référence, il y a le catch par référence-constante. Celui par référence pouvant être réservé aux cas où l'on veut altérer/enrichir la description d'une exception.
Autant sur les std::string on peut comprendre (la référence) pour des raisons d'optimisation et surtout d'éviter des copies pouvant être refusées, autant sur des int, cela n'a pas de sens. (dans _c_es deux cas, l'argument de l'héritage ne tenant pas)

c- Attention à dire que typiquement une division par zéro doit être traitée par exception. C'est un raccourci qui peut engendrer des incompréhensions au sujet des exceptions. Il y a des cas, comme ton exemple de calculatrice, où effectivement une division par zéro est une erreur qui survient suite à un problème dynamique lors de l'exécution (l'utilisateur humain à tapé "/0"). Mais il y a de nombreux autres cas où une division par zéro est bel et bien une erreur de programmation ou de conception: "l'algo était prévu pour que, par construction, le déterminant de la matrice (utilisé ensuite dans une division) ne soit jamais nul, et pourtant..."
(et là on utilise d'abord les assertions, que l'on double éventuellement d'exception si cela a du sens ou si on doute des procédures de tests)

Je vois que Kurlze/L.O.S.T a mis le doigt sur ce problème quand il demande pourquoi ne pas tester avant.

d- La classe Erreur devrait recevoir un "char const*" et pas un "char*". Au moins on autorise _officiellement_ (à cause de pratiques héritées du C il y a certains laxismes à ce sujet) les chaines constantes littérales. Car si on sous-entend d'autres mécanismes, on est partis dans des horreurs d'appropriation/duplication/... que les std::string gèrent pour nous.

En fait, on a tendance à considérer que si on ne peut même pas allouer une petite std::string, de toutes façons il n'y a plus grand chose que l'on puisse faire. Que le programme plante où que l'utilisateur soit forcé de l'arrêter suite à une popup lui disant qu'il n'y a plus de mémoire (si tant est que l'on puisse la déclencher)... cela ne fait plus grande différence: c'est la fin.

e- de la gestion déterministe des ressources...
En java:
- le dispose-pattern (-> finally) + le GC pour la mémoire
En C#
- Comme en Java, mais il y a aussi un nouveau mot clé (using) qui déclenche le dispose (mais pas la récupération de la mémoire)
En C++
- le RAII qui traite toutes les ressources de manière identique.

Certains préfèrent finally, d'autres le RAII. Probablement une question d'habitude.

Bref, tout ça pour dire qu'il n'y a pas de finally car on n'en a pas besoin, vu que l'on a le RAII.

Cet idiome est PRIMORDIAL dans la compréhension de l'utilisation des exceptions en C++. try, catch, throw, ce n'est que de la syntaxe. Le RAII est la bonne pratique qui nous permet de survivre tranquillement.

Je vois que tu avais répondu à David au sujet de la complexité du bestio. Les analogies c'est certes mal, mais je vois un peu les exceptions sans le RAII comme une roue de vélo sans rayons. C'est cool, on peut jouer avec. Mais sur un vrai projet (/une vraie route), on en bave sans. C'est impécable pour entretenir les a priori comme quoi les exceptions sont compliquées.

Au pire, il y a toujours moyen de donner un lien vers la FAQ de développez. "En C++, il n'y a pas de finally, à la place la gestion déterministe des ressources est réalisée à l'aide de l'idiome RAII [lien]". Par exemple.


f- Les spécifications d'exception sont des attrape-couillons. Leur seule utilité, c'est de faire planter (au mieux s'arrêter en passant par une fonction donnée) le programme si une exception du mauvais type s'échappe d'une fonction. C'est le genre d'idiotie qui est uniquement vérifiée lors de l'exécution.
Le langage est trop complexe pour que le compilo soit capable de vérifier statiquement (à la compilation donc!) que seules les seules exceptions pouvant remonter sont bien celles spécifiées et pas d'autres.

Aujourd'hui, les consignes sont "hors problème, d'utilisation de certains frameworks dont on dérive des classes, pas de spécification d'exception dans le code".

(et à cause du throw(), c'est difficile de les passer sous silence -- pour la doc un bon commentaire est tout aussi bien, sinon mieux)

g- Pour l'exemple des deux tableaux, pas besoin du second delete (en l'absence d'une 3e ressource brute dont la classe serait responsable)




Voilà, sinon très bonne initiative! Et sinon, je ne suis plus assez débutant pour m'en rendre compte, mais cela m'a l'air bien.


(C'est terrible ce système de commentaires des tutos: pas de citations, pas de notifications, et malgré tout des questions techniques y sont posées :-/)
 
Hors ligne Nanoc # Posté le 27/03/2008 21:14:04
Apprenez à utiliser la STL !!
Avatar
Groupe : Membres
Merci à toi pour tes remarques. J'ai fait quelques modifications en conséquence.

a) Corrigé

b) Le passage par référence constante est quand même une bonne habitude à prendre. Vu qu'on ne lance jamais des types de bases dans les cas normaux.

c) J'ai ajouté un commentaire allant dans ce sens.

d) C'est vrai que si on a plus de string, c'est grave. Mais j'aurais tendance à dire que vu qu'on utilise la chaîne que pour l'afficher, le recours à string n'est pas nécessaire.

e) J'ai modifié la remarque sur le RAII en mettant des liens adéquats et en ajoutant un commentaire plus complet.

f) J'ai ajouté un commentaire allant dans ce sens. J'aurais dû y penser avant...

g) Corrigé

Encore merci pour tes compléments et remarques toujours pertinents.
 
Hors ligne zero ptt # Posté le 03/06/2008 15:16:33
Avatar
Groupe : Bannis
faut dire aussi qu'il ne faut pas employé les exceptions a tout va(sauf erreur vraiment fatal), et que ça reduit la lisibilité du programme!

mon tout nouveau siteweb: Creations

regroupe tous mes programmes de A à Z :soleil: (piur me soutenir, un clic sur la pub suffit)
attention, google arrive :lol:
 

Vous devez être inscrit pour pouvoir poster des messages

Retour au tutoriel

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | Fil RSS | XHTML 1.0 | CSS 2.0
Édité par Simple IT SARL : Nous contacter | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 774 Zéros connectés | Requêtes SQL 7 requêtes | Temps de génération de la page : Total (SQL) 0.0582s (0.042s)