Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

De l'usage des exceptions

106 réponses
Avatar
Guillaume Gourdin
Bonjour à tous,

selon ma (modeste) expérience, les exceptions en C++sont très largement sous
utilisées, et on en reste (me semble t-il) toujours à la bonne vieille
méthode du retour d'un code d'erreur. Je suis un peu surpris de cet état de
fait, les exceptions étant supposées apporter une gestion plus performantes
des erreurs. J'ai dons quelques questions: est-il vrai que les exceptions
sont sous utilisées? Quels sont vos retours d'expérience? Ou bien y a t'il
une raison plus profonde à la sous-utilisation des exceptions?

Merci!

- Guillaume -

10 réponses

Avatar
Michael Doubez
On 7 juil, 12:07, James Kanze wrote:
On Jul 6, 12:01 pm, Michael Doubez wrote:

> On 5 juil, 12:07, James Kanze wrote:
> > On Jul 4, 12:34 pm, "Guillaume Gourdin" wrote:
> > > selon ma (modeste) expérience, les exceptions en C++sont très
> > > largement sous utilisées,
> > Ça dépend. D'après mon expérience, elles servent souvent trop .
> [snip]
> > > Quels sont vos retours d'expérience? Ou bien y a t'il une
> > > raison plus profonde à la sous-utilisation des exceptions?
> > Mon expérience, c'est, précisement, qu'elles sont sur-utilisées .
> > Surtout parmi les programmeurs plus jeunes.
> AMA il y a aussi une mode de l'expressivité d'un programme (style DSL )
> et comme la gestion d'erreur brise la linéarité de l'expression, le s
> exceptions sont alors vues comme une solution pour /préserver/ la
> lecture du programme en segmentant le programme en "logique
> d'application"/"gestion d'erreur".

La linéarité de l'expression de quoi, exactement ?Très peut
d'algorithmes sont linéaire.



Je ne pensais pas à l'algorithme en lui même mais en l'expression
d'une logique dont la linéarité assure une certaine lisibilité.
L'insertion de la gestion des erreurs/log ... a quand même tendance a
compliqué la lecture, ne serait ce que par la longueur du code.

Je ne me fais pas l'avocat de l'utilisation des exception, au
contraire, je note seulement cette tendance /parmi les programmeurs
plus jeunes/ consistant à les utiliser comme un moyen de séparer "tout
va bien" de "il y a eu une erreur".
Peut être y a t il une relation avec la programmation fonctionnelle.

Concernant, les altenatives aux exceptions (comme Fallible) qui
préservent la lisibilité, je ne les ait pas souvent vu dans la nature.

La question est simplement si le
traitement de l'erreur fait partie de l'algorithme ou non. Ce
qui dépend de l'algorithme, et du type de l'erreur. (Dans la
pratique, quand la gestion de l'erreur ne fait pas partie de
l'algorithme, on a une facheuse tendance à l'oublier
complètement.)

Les exceptions introduisent des arcs supplémentaires dans la
graphe du flux du programme, ce qui complique l'analyse. Il y a
des façons à les traiter autrement, mais elles sont peu connues,
et sont des analyses supplémentaires qu'il faut faire pour
s'assurer la correction du code. C'est un coût supplémentaire.
Dans les cas où les exceptions apportent une reduction des coûts
par ailleurs, bien. Sinon, non.



Je suis d'accord dans le cas d'une analyse mais dans le cas de la
compréhension d'un code, les exceptions permettent de segmenter
l'analyse: si je vois un throw, je sais que je sors de la boite et
retourne à un état antérieur avec un traitement spécial que je peux
explorer plus tard.

--
Michael
Avatar
ld
On 7 juil, 11:17, James Kanze wrote:
On Jul 6, 11:53 am, ld wrote:





> On 6 juil, 10:24, James Kanze wrote:
> > On Jul 5, 7:01 pm, Gabriel Dos Reis wrote:
> > > James Kanze writes:
> > > [...]
> > > > > > D'ailleurs, par défaut, les iostream ne lancent pas
> > > > > > d'exception en cas d'erreur.
> > > > > C'est un tort !
> > > > Tu rigoles, non ? Tu ne vas pas dire qu'une erreur de format
> > > > dans une entrée d'utilisateur est un cas « exceptionnel ». Ou
> > > > arriver à la fin du fichier.
> > > À noter cependant que les IOStreams peuvent lever des
> > > exceptions, si on le désire.
> > Certes. Si ça a un sens, c'est une autre question -- une
> > exception si le eofbit est positionné n'a jamais de sens,
> Tu viens de donner toi-meme un exemple ou ca a un sens: un
> parser descendant. Si le parser voit eofbit alors qu'il a des
> regles "en cours", c'est que le format des donnees est
> incorrect.

Tout ce que le eofbit signifie, c'est que le istream a vu la fin
de fichier, peut-être dans son look-ahead à lui.



Je parlais de l'interpretation du eofbit, pas du fait que le stream
devait leve une exception sur un eofbit.

Ceci dit, j'etais peut-etre hors sujet dans mes propos car comme le
disais Gaby, je pensais aux "parser combinator" ou un echec n'est pas
une exception et ou une fin de fichier peut etre une exception
(dependant du contexte). Mais tout ceci n'etait que l'interpretation
du eofbit du stream par le parseur et non par le stream lui-meme.
C'est ton mot a propos des parseurs recursifs descendants qui m'a fait
penser que tu parlais de la meme chose sans le mentionner.

Il n'a de
signification pour le client qu'après l'échec d'une lecture (et
c'est surtout une signification inversée -- s'il n'est pas
positionné, alors que failbit l'est, c'est qu'il y a une erreur
de format dans le fichier). La raison pourquoi il ne fait jamais
de sens qu'il génère une exception, c'est précisement parce
qu'il ne signifie rien pour le client, qu'il peut être
positionné d'une façon un peu aléatoire, non selon ce qu'on
vient de lire (ou qu'on vient d'essayer à lire), mais selon ce
qui suit dans le fichier, et même la façon que istream
fonctionne internellement.



? Pas tout compris... Si on voit un eofbit, c'est que la fin de
fichier a ete _effectivement_ vue, pas seulement que l'on s'y trouve.

> Donc dans un cas (regles terminees), le eofbit n'est pas une
> erreur alors que dans l'autre cas (format invalide), c'est une
> erreur normalement exceptionnelle. On peut evidement mettre le
> parseur dans etat special (son propre badbit) et le retouner a
> tous les etages. Mais comme tu l'as dit, c'est un cas typique
> ou les exceptions simplifient le code de gestion des erreurs.

Certes, mais même dans ce cas-là, je ne vois pas d'exception en
provenance d'istream. Tout au plus quelque chose du genre :

    //  Ici, il nous faut un entier...
    int             quelqueChose ;
    source >> quelqueChose ;
    if ( ! source ) {
        throw ParserError( "integral value needed" ) ;
    }



je pensais plutot a quelque chose comme:

if (! (readInt(parser) || readFloat(parser) || readDate(parser) ||
readString(parser)))
throw parser.error("syntax error: invalid field value");

note que c'est le parser lui-meme que je "throw", car il contient les
informations sur l'etat courant du parsing (history, location,
remaining, context) qui permet de detailler le rapport de l'erreur.

a+, ld.
Avatar
Jean-Marc Bourguet
ld writes:

Ceci dit, j'etais peut-etre hors sujet dans mes propos car comme le
disais Gaby, je pensais aux "parser combinator" ou un echec n'est pas
une exception et ou une fin de fichier peut etre une exception
(dependant du contexte).



Mais dans ce cas, l'entree du parseur est quelque d'autres qu'un flux et
est plus proche de la combinaison d'un flux avec une position dans ce flux
pour pouvoir faire du backtracking

if (! (readInt(parser) || readFloat(parser) || readDate(parser) ||
readString(parser)))
throw parser.error("syntax error: invalid field value");

note que c'est le parser lui-meme que je "throw", car il contient les
informations sur l'etat courant du parsing (history, location, remaining,
context) qui permet de detailler le rapport de l'erreur.



A priori, si j'ai un objet parseur qui a autant d'etat, il ne va pas etre
copiable et ne pourra pas servir comme exception. Peut-etre que l'avoir
copiable sert pour le backtracking? Mais ici, j'ai plutot l'impression que
ce sont les readXXX qui ont pour responsabilite ou de modifie l'etat du
parseur s'ils reussissent, ou de ne pas le modifier s'ils echouent.

Et le throw me semble mal cadrer avec l'idee des combinateurs. A moins de
vouloir se servir du throw ici comme on servirait en prolog d'un cut avant
une regle qui n'est jamais acceptee. Et quel message d'erreur obtient-on
si on n'a jamais d'exception mais que le parsing echoue?

Note que je comprends bien dans ce contexte une exception en cas d'erreur
d'IO, mais la fin de fichier me semble etre un cas ou il faut du
backtracking.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
Wykaaa
James Kanze a écrit :
On Jul 6, 2:08 pm, Wykaaa wrote:
James Kanze a écrit :
D'une part, les exceptions n'existent pas en C, et leur
support en C++ est "récent". Du coup, les gens qui
programment toujours soit en C, soit en C++ "ancien", on du
mal à s'y faire. De plus, beaucoup de bibliothèques, écrites
en C, ne gèrent pas les exceptions.


Qu'entends-tu par "récent" ?
Ca existait déjà dans le C++ au moins en 1990...







Ah bon. Dans quel compilateur ? Certainement g++. Ni CFront.
Ni Zortech.





Dans mon cours C++ de 90, les exceptions étaient déjà traitées
en détail et les compilateurs des constructeurs (Sun, HP, IBM
au moins) les traitaient. Le compilateur Borland les traitait
également. Remarque : Zortech, c'est avant 90 non ? plutôt
88.



La première publication sur la *possibilité* d'exceptions en C++
date de 1989 ("Exception Handling for C++", de Koenig et
Stroustrup). Les premières implémentations (Lucid, je crois)
date de 1992, et pendant longtemps, les exceptions restaient
rare. CFront ne les a jamais supporté (à part une modification
fait par HP pour son propre compilateur), Zortech ne les a
jamais supporté, Borland ne s'est mis à les supporter qu'assez
tardivement, Microsoft et g++ encore plus tardivement (2.8 ou
2.9 pour g++ ? C-à-d environ 1998 ou 1999).



Oui, tu as raison. J'ai certainement trop lu le ARM en 90 et mon cours
s'en inspirait fortement ;-)

Dans la pratique, dans l'industrie, on n'a pu réelement
commencer à se servir des exceptions que vers 2000 (plus ou
moins un an ou deux, selon les besoins de portabilité et de
fiabilité).

D'autre part, il n'y a pas vraiment de consensus sur
l'étendue d'utilisation des exceptions. Certains pensent
qu'il faut les réserver à des cas vraiment exceptionnels,
qui ne devraient pas se produire lors du déroulement
normal du programme. Exemple : pas assez de mémoire pour
créer un objet, tentative de prendre le cinquième élément
d'un tableau qui n'en comporte que trois, etc.









L'exemple du tableau est plutôt un bug de programmation. Ce
n'est pas une situation exceptionnelle comme le "pas assez
de mémoire".







Exacte. Dans la plupart des applications, il vaut mieux
carrément avorter -- la situation ne peut pas se produire, elle
s'est produite, on ne peut donc plus raisonner sur le code, et
tout ce qu'on fait risque de rendre la situation pire. (Il y a
des exceptions, évidemment. Des jeux, par exemple, mais aussi
probablement certaines services Web non critiques.)





Il faut aussi se préoccuper des systèmes "fault tolerant".



La « fault tolerance » s'acquit grace à la rédundance. En cas
d'erreur, il faut que le processeur en cause se mette hors jeu
le plus rapidement possible, afin que d'autres puissent en
reprendre le relai. C'est l'exemple même où une exception serait
un mauvais choix pour une erreur « impossible ».

[...]
Note aussi que si la fonction appelante comporte directement
le code de traitement d'erreur en cas d'échec de la fonction
appelée, utiliser un code de retour est plus facile. Les
exceptions deviennent utiles s'il faut remonter de plusieurs
appels de fonctions pour trouver le code de traitement
d'erreur.









Je ne suis pas d'accord avec ton dernier paragraphe.







Il a cependant clairement raison. Quelque chose comme :





if ( someAction() != success ) {
// traiter l'erreur...
}





est bien plus simple à comprendre et à maintenir que quelque
chose du genre :





try {
someAction() ;
// qui sait quoi de plus...
} catch ( errorCode ) {
// traiter erreur concernant someAction
}





Ben non. Il est préférable d'utiliser la seconde forme.



Absolument pas. Distinquer les « erreurs » d'autres conditions
relève de l'obfuscation. Si l'erreur n'est pas exceptionnelle,
il ne faut pas le traiter comme si elle était.

Et si on veut traiter l'exception au plus proche de sa
survenue, on ne mettra pas "qui sait quoi de plus..." dans le
"try" !



Ce qui impose que someAction() soit dans un bloc à soi, avec son
propre portée. Quelque chose comme :

try {
MyType var = someAction() ;
} catch ...

ne va pas si var doit servir ulterieurement.



je déclare var au niveau de la fonction bien que ça contredise la règle
"déclarer les variables au plus proche de leur utilisation". Je ne suis
pas pour déclarer des variables dans les blocs try.

[...]
Exactement. S'il faut gerer l'erreur tout de suite,
l'utilisation d'une exception est à proscrire. (Il ne faut pas
oublier qu'en fin de compte, une exception n'est autre chose
qu'un goto maquillé.)





Oui mais c'est le compilateur qui le gère, ce qui fait toute la
différence...



Oui et non. C'est un cheminement supplémentaire, qu'on ne peut
pas negliger dans l'analyse du code.



L'outil Logiscope les identifie différemment des goto.

Remarque : un if-else, génère aussi, souvent, un goto en
assembleur ainsi qu'un while, si tu vas par là. Ce n'est pas
un argument.



Un if-else est struturé. Le cheminement suite à une exception ne
l'est pas.



Ma (longue) expérience sur la qualité du code est que, à terme
(c'est-à-dire dans la durée), il est presque toujours préférable
d'utiliser le mécanisme d'exception que les codes retour. C'est beaucoup
plus facile à maintenir et à faire évoluer.
Avatar
Jean-Marc Bourguet
Wykaaa writes:

Ma (longue) expérience sur la qualité du code est que, à terme
(c'est-à-dire dans la durée), il est presque toujours préférable
d'utiliser le mécanisme d'exception que les codes retour. C'est beaucoup
plus facile à maintenir et à faire évoluer.



Exemple a reecrire avec quelque chose qui utilise les exceptions pour
signifier que l'ouverture d'un fichier a echoue (que ce soit le mecanisme
des IOStreams ou tu peux concevoir ta bibliotheque si tu trouves que les
IOStreams ne sont pas bien concues sur ce point).

std::ifstream is(fileName.c_str());
if (! is) {
assert(!defaultExt.empty() && defaultExt[0] == '.');
is.open((fileName + defaultExt" ).c_str());
}
if (! is) {
assert(!defaultDir.empty() && defaultDir.last() == '/');
is.open((defaultDir + fileName).c_str());
}
if (! is) {
is.open((defaultDir + fileName + defaultExt).c_ctr());
}
if (! is) {
throw std::runtime_error("Unable to open '" + fileName +"'" );
// mais une exception plus adaptée au projet est vraisemblablement à utiliser
}

Un critere du choix pour savoir si une fonction d'interface doit utiliser
une exception pour signifier une erreur ou un autre mecanisme, c'est
"est-ce que c'est l'appelant immediat qui va devoir faire quelque chose ou
se contentera-t'il generalement de transmettre?" Quelque chose de
potentiellement utile, c'est un code d'erreur degenerant en une exception
s'il n'est pas traite. Mais je ne l'ai jamais mis en oeuvre et c'est
peut-etre une fausse bonne idee.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
ld
On 7 juil, 15:37, Jean-Marc Bourguet wrote:
ld writes:
> Ceci dit, j'etais peut-etre hors sujet dans mes propos car comme le
> disais Gaby, je pensais aux "parser combinator" ou un echec n'est pas
> une exception et ou une fin de fichier peut etre une exception
> (dependant du contexte).

Mais dans ce cas, l'entree du parseur est quelque d'autres qu'un flux et
est plus proche de la combinaison d'un flux avec une position dans ce flu x
pour pouvoir faire du backtracking



le backtracking est plutot gere par le parser pour etre independant de
la nature du stream (not seekable).

> if (! (readInt(parser) || readFloat(parser) || readDate(parser) ||
> readString(parser)))
>   throw parser.error("syntax error: invalid field value");

> note que c'est le parser lui-meme que je "throw", car il contient les
> informations sur l'etat courant du parsing (history, location, remainin g,
> context) qui permet de detailler le rapport de l'erreur.

A priori, si j'ai un objet parseur qui a autant d'etat



il n'a pas "autant" d'etats? je ne comprends pas cette phrase.

il ne va pas etre
copiable et ne pourra pas servir comme exception.



il n'a pas besoin de l'etre (tout comme les streams). Ce qui veut dire
que le try-catch doit etre dans le scope de sa duree de vie, mais ca
parait plutot normal pour un parseur recursif.

 Peut-etre que l'avoir
copiable sert pour le backtracking?  Mais ici, j'ai plutot l'impression que
ce sont les readXXX qui ont pour responsabilite ou de modifie l'etat du
parseur s'ils reussissent, ou de ne pas le modifier s'ils echouent.



Il ne modifie pas le parseur, ce sont des combinators qui demande au
parseur de valider un input en utilisant des combinator de plus bas
niveau (char ou wchar_t). Et c'est la raison pour laquelle ils ne sont
pas membre. C'est le parseur qui track ou il en est. Libre ensuite de
convertir la validation courante en objet (type).

Et le throw me semble mal cadrer avec l'idee des combinateurs.



En principe tu renvoie un boolean, a moins d'overloader bool(), && et
|| et de retourner le parser lui-meme comme pour les streams. C'etait
pour donner un exemple un peu extreme ou on cherche a se "deplacer"
plus vite d'un contexte a l'autre (un erreur n'est qu'un contexte
particulier).

 A moins de
vouloir se servir du throw ici comme on servirait en prolog d'un cut avan t
une regle qui n'est jamais acceptee.
 Et quel message d'erreur obtient-on
si on n'a jamais d'exception mais que le parsing echoue?



L'exception ici c'etait juste pour remonter la recursion, pas pour
indiquer le type de l'erreur. L'erreur, il faut la demander au parseur
dans le catch, ainsi que le numero de ligne/colonne, etc qui font
parti du contexte courant avant l'echec.

Note que je comprends bien dans ce contexte une exception en cas d'erreur
d'IO, mais la fin de fichier me semble etre un cas ou il faut du
backtracking.



un parseur combinator a pour role essentiel de gerer le backtracking
et les changements de contexte efficacement ;-) ce qui permet a
l'utilisateur de coder ses regles "a la main" de facon tres simple.

a+, ld.
Avatar
Jean-Marc Bourguet
ld writes:

On 7 juil, 15:37, Jean-Marc Bourguet wrote:
> ld writes:
> > Ceci dit, j'etais peut-etre hors sujet dans mes propos car comme le
> > disais Gaby, je pensais aux "parser combinator" ou un echec n'est pas
> > une exception et ou une fin de fichier peut etre une exception
> > (dependant du contexte).
>
> Mais dans ce cas, l'entree du parseur est quelque d'autres qu'un flux et
> est plus proche de la combinaison d'un flux avec une position dans ce flux
> pour pouvoir faire du backtracking

le backtracking est plutot gere par le parser pour etre independant de
la nature du stream (not seekable).



Ok, simplement difference de conception, j'aurais introduit un
intermediaire pour cela (mais j'aurais aussi introduit un intermediaire
s'occupant de la transformation caracteres -> lexemes plutot que de fournir
des caracteres au parseur; il y a des erreurs qui sont plus faciles a
signaler comme cela).

> > if (! (readInt(parser) || readFloat(parser) || readDate(parser) ||
> > readString(parser)))
> >   throw parser.error("syntax error: invalid field value");
>
> > note que c'est le parser lui-meme que je "throw", car il contient les
> > informations sur l'etat courant du parsing (history, location, remaining,
> > context) qui permet de detailler le rapport de l'erreur.
>
> A priori, si j'ai un objet parseur qui a autant d'etat

il n'a pas "autant" d'etats? je ne comprends pas cette phrase.



le parseur contient beaucoup d'etat visiblement

> il ne va pas etre copiable et ne pourra pas servir comme exception.

il n'a pas besoin de l'etre (tout comme les streams).



On ne peut pas jeter un type non copiable (meme si l'exception est
recuperee par reference, elle est d'abord copiee).

Ce qui veut dire que le try-catch doit etre dans le scope de sa duree de
vie, mais ca parait plutot normal pour un parseur recursif.

>  Peut-etre que l'avoir
> copiable sert pour le backtracking?  Mais ici, j'ai plutot l'impression que
> ce sont les readXXX qui ont pour responsabilite ou de modifie l'etat du
> parseur s'ils reussissent, ou de ne pas le modifier s'ils echouent.

Il ne modifie pas le parseur, ce sont des combinators qui demande au
parseur de valider un input en utilisant des combinator de plus bas
niveau (char ou wchar_t). Et c'est la raison pour laquelle ils ne sont
pas membre. C'est le parseur qui track ou il en est. Libre ensuite de
convertir la validation courante en objet (type).



As-tu une reference? Le nom m'evoque une technique qui est proche, mais
visiblement il y a des details qui different au point que nous ne nous
comprennons pas du tout. En particulier, tu as l'air d'impliquer qu'on
peut avoir des messages d'erreur raisonnables pour une description qui ne
tient pas compte de ca, alors qu'utilisee de maniere trop naive, la
technique que je connais donne facilement des messages d'erreur
inutilisables, pires que le "syntax error" de yacc car ils ne pointent meme
pas a la fin du prefixe viable le plus long (on peut relativement
facilement arriver a cela, mais c'est quand meme le degre 0 du message
d'erreur).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
Sylvain SF
James Kanze a écrit :

La première publication sur la *possibilité* d'exceptions en C++
date de 1989 ("Exception Handling for C++", de Koenig et
Stroustrup).



suivi d'autres articles vers 1922-1994 avec des implémentations
concrètes de support d'exception (par setjmp/longjmp).

Dans la pratique, dans l'industrie, on n'a pu réelement
commencer à se servir des exceptions que vers 2000.



à s'en servir de manière standard (mots clés try, catch).
je les utilisais (et ce n'était pas un usage isolé) dès
1995-1996 dans tous mes codes C++ (CFront sous MPW/MacOS).

juste pour pinailler sur quelques années, cela ne change pas
le fond.

SF.
Avatar
Wykaaa
Gabriel Dos Reis a écrit :
Wykaaa writes:

| Gabriel Dos Reis a écrit :
| > Amrein-Marie Christophe writes:
| >
| > | Gabriel Dos Reis wrote:
| > | | > Wykaaa writes:
| > | > | > [...]
| > | > | > | C'est une question de méthodologie, de lisibilité et de
| > maintenabilité.
| > | > | De plus, on peut facilement changer le catch au profit de la capture
| > | > | d'une exception plus générale que l'exception spécifique qu'on a
| > | > | "attrapé" dans la première version d'un logiciel.
| > | > | > Et il savoir apprécier le cas où un code d'erreur de retour
| > est
| > | > préférable à une exception.
| > | > | > -- Gaby
| > | | Personnellement, depuis que j'ai touché à Java et .Net, je gère
| > les erreurs
| > | en C++ sous forme d'exceptions. Toujours.
| > | | C'est deux façons différentes de traiter les erreurs et on est
| > libre de
| > | faire comme on veut mais franchement, de mon point de vu, on a beau avoir
| > | le choix, le code est plus propre et plus flexible avec les exceptions.
| > | | A chacun son truc.
| >
| > Une erreur courante chez les nouveaux convertis, c'est de croire que
| > l'un des mécanismes est universellement supérieur à l'autre.
| >
| > -- Gaby
|
| Ok, mais en l'occurrence c'est le cas.

Parce que tu le dis ? Ou parce que tu offres des arguments rationnels ?



Je ne saurais mieux dire que ce qui est dit dans le § 17.1 ici :
http://www.parashift.com/c++-faq-lite/exceptions.html

| Je dirai même que le traitement
| par les exceptions est INFINIMENT supérieur à la méthode des codes
| d'erreurs. D'ailleurs tous les langages "modernes" ont une syntaxe
| pour le traitement des exceptions.

Et donc ?
(offrir != obliger).



On est d'accord mais on peut avoir des préférences...

| C'est même un critère de choix de langage dans beaucoup de milieux.

-- Gaby


Avatar
Gabriel Dos Reis
Wykaaa writes:

| Gabriel Dos Reis a écrit :
| > Wykaaa writes:
| >
| > | Gabriel Dos Reis a écrit :
| > | > Amrein-Marie Christophe writes:
| > | >
| > | > | Gabriel Dos Reis wrote:
| > | > | | > Wykaaa writes:
| > | > | > | > [...]
| > | > | > | > | C'est une question de méthodologie, de lisibilità © et de
| > | > maintenabilité.
| > | > | > | De plus, on peut facilement changer le catch au profit de la capture
| > | > | > | d'une exception plus générale que l'exception spà ©cifique qu'on a
| > | > | > | "attrapé" dans la première version d'un logiciel.
| > | > | > | > Et il savoir apprécier le cas où un code d'erreur de retour
| > | > est
| > | > | > préférable à une exception.
| > | > | > | > -- Gaby
| > | > | | Personnellement, depuis que j'ai touché à Java et .Ne t, je gère
| > | > les erreurs
| > | > | en C++ sous forme d'exceptions. Toujours.
| > | > | | C'est deux façons différentes de traiter les erreurs et on est
| > | > libre de
| > | > | faire comme on veut mais franchement, de mon point de vu, on a be au avoir
| > | > | le choix, le code est plus propre et plus flexible avec les excep tions.
| > | > | | A chacun son truc.
| > | >
| > | > Une erreur courante chez les nouveaux convertis, c'est de croire que
| > | > l'un des mécanismes est universellement supérieur à l'autre. |
| > >
| > | > -- Gaby
| > | | Ok, mais en l'occurrence c'est le cas.
| >
| > Parce que tu le dis ? Ou parce que tu offres des arguments rationnels ?
|
| Je ne saurais mieux dire que ce qui est dit dans le § 17.1 ici :
| http://www.parashift.com/c++-faq-lite/exceptions.html

À noter que le paragraphe en question dit pas que les exceptions sont
universellement supérieures. En fait, ce paragraphe reconnaît
implicitement que les codes d'erreur peuvent dans certains être mieux
appropriés :

Although the return code technique is sometimes the most appropriate
error handling technique, there are some nasty side effects to adding
unnecessary if statements:

| > | Je dirai même que le traitement
| > | par les exceptions est INFINIMENT supérieur à la métho de des codes
| > | d'erreurs. D'ailleurs tous les langages "modernes" ont une syntaxe
| > | pour le traitement des exceptions.
| >
| > Et donc ? (offrir != obliger).
|
| On est d'accord mais on peut avoir des préférences...

Sure.

-- Gaby