On Sat, 04 Jul 2009 16:22:43 +0200, Wykaaa :
>> 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.
T'es sûr ?
Imagine le cas suivant : j'ai chargé un fichier ligne par ligne dans
un vector<string>. Les spécifications de ce fichier indiquent
clairement qu'il doit contenir 5 lignes. Si le fichier est mal formé,
je ne peux qu'arrêter le programme.
Je pourrais écrire :
if (lignes.size() < 5)
throw quelque_chose;
f (lignes[4]);
Sauf que... la fonction at() fait déjà ça pour moi ! Pourquoi
réinventer la roue ?
On Sat, 04 Jul 2009 16:22:43 +0200, Wykaaa <wyk...@yahoo.fr>:
>> 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.
T'es sûr ?
Imagine le cas suivant : j'ai chargé un fichier ligne par ligne dans
un vector<string>. Les spécifications de ce fichier indiquent
clairement qu'il doit contenir 5 lignes. Si le fichier est mal formé,
je ne peux qu'arrêter le programme.
Je pourrais écrire :
if (lignes.size() < 5)
throw quelque_chose;
f (lignes[4]);
Sauf que... la fonction at() fait déjà ça pour moi ! Pourquoi
réinventer la roue ?
On Sat, 04 Jul 2009 16:22:43 +0200, Wykaaa :
>> 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.
T'es sûr ?
Imagine le cas suivant : j'ai chargé un fichier ligne par ligne dans
un vector<string>. Les spécifications de ce fichier indiquent
clairement qu'il doit contenir 5 lignes. Si le fichier est mal formé,
je ne peux qu'arrêter le programme.
Je pourrais écrire :
if (lignes.size() < 5)
throw quelque_chose;
f (lignes[4]);
Sauf que... la fonction at() fait déjà ça pour moi ! Pourquoi
réinventer la roue ?
En général, je crois qu'il y a trois types d'erreur :
-- Les erreurs « attendues ». Dans un certain sens, ce ne sont
pas des erreurs, puisqu'on s'y attend, ou qu'on doit s'y
attendre. Ou plutôt, elles sont des erreurs de la part de
l'utilisateur : des fautes de frappe en entrée, par exemple.
En général, traiter ces erreurs doit faire partie de
l'« algorithme », ce qui fait que la meilleur façon de les
annoncer, c'est par un code de retour.
-- Les erreurs « exceptionnelles ». Ce sont des erreurs
auxquelles on ne s'attend pas normalement, mais qu'on sait
peuvent arriver, et qu'on peut vouloir traiter, mais à un
niveau plus élevé, loin d'où l'erreur est detectée. Ce sont
les erreurs pour lesquelles les exceptions conviennent.
-- Les erreurs « impossible ». Ce sont des erreurs qui ne
peuvent pas arriver, tant que le hardware marche et qu'il
n'y a pas d'erreur dans le code. Une violation d'un
invariant, par exemple, ou une faute de parité mémoire
(panne ou défaillance hardware). En général, devant de
telles erreurs, on ne peut rien, et il faut mieux avorter le
programme le plus vite possible.
Mais une telle classification (encore si généralement reconnu
par les experts) est assez catégorique. D'une part, selon
l'application, la même erreur peut être considérer dans une
catégorie ou dans une autre -- considérons un serveur LDAP, qui
traite des requêtes arbitraires formulées en ASN.1, avec un
parseur à déscent récursif pour les interprêter. Comment
catégoriser un débordement de pile dans le parseur Logiquement,
selon la description ci-dessus, c'est une erreur à laquelle il
faut s'y attendre, puisqu'il faut s'attendre à tout d'un
utilisateur. Pratiquement, en revanche, le seul traitement
possible, c'est d'avorter la requête entière, c-à-d de le
traiter à un niveau bien plus élevé dans la pile d'appels, ce
qui argue très fortement pour une exception. Et dans bien des
cas, pratiquement, on ne va pas pouvoir le detecter, même si
elle se produit, parce qu'on ne sait pas (au niveau C++)
détecter un débordement de pile -- du coup, elle devient
« impossible » (et dans la pratique, sous Windows ou Unix, fera
avorter le programme).
Et il y a des considérations très pragmatiques aussi dans
certains cas. Des fonctions comme les constructeurs ou les
opérateurs surchargés ne peuvent pas renvoyer un code de retour.
En général, je crois qu'il y a trois types d'erreur :
-- Les erreurs « attendues ». Dans un certain sens, ce ne sont
pas des erreurs, puisqu'on s'y attend, ou qu'on doit s'y
attendre. Ou plutôt, elles sont des erreurs de la part de
l'utilisateur : des fautes de frappe en entrée, par exemple.
En général, traiter ces erreurs doit faire partie de
l'« algorithme », ce qui fait que la meilleur façon de les
annoncer, c'est par un code de retour.
-- Les erreurs « exceptionnelles ». Ce sont des erreurs
auxquelles on ne s'attend pas normalement, mais qu'on sait
peuvent arriver, et qu'on peut vouloir traiter, mais à un
niveau plus élevé, loin d'où l'erreur est detectée. Ce sont
les erreurs pour lesquelles les exceptions conviennent.
-- Les erreurs « impossible ». Ce sont des erreurs qui ne
peuvent pas arriver, tant que le hardware marche et qu'il
n'y a pas d'erreur dans le code. Une violation d'un
invariant, par exemple, ou une faute de parité mémoire
(panne ou défaillance hardware). En général, devant de
telles erreurs, on ne peut rien, et il faut mieux avorter le
programme le plus vite possible.
Mais une telle classification (encore si généralement reconnu
par les experts) est assez catégorique. D'une part, selon
l'application, la même erreur peut être considérer dans une
catégorie ou dans une autre -- considérons un serveur LDAP, qui
traite des requêtes arbitraires formulées en ASN.1, avec un
parseur à déscent récursif pour les interprêter. Comment
catégoriser un débordement de pile dans le parseur Logiquement,
selon la description ci-dessus, c'est une erreur à laquelle il
faut s'y attendre, puisqu'il faut s'attendre à tout d'un
utilisateur. Pratiquement, en revanche, le seul traitement
possible, c'est d'avorter la requête entière, c-à-d de le
traiter à un niveau bien plus élevé dans la pile d'appels, ce
qui argue très fortement pour une exception. Et dans bien des
cas, pratiquement, on ne va pas pouvoir le detecter, même si
elle se produit, parce qu'on ne sait pas (au niveau C++)
détecter un débordement de pile -- du coup, elle devient
« impossible » (et dans la pratique, sous Windows ou Unix, fera
avorter le programme).
Et il y a des considérations très pragmatiques aussi dans
certains cas. Des fonctions comme les constructeurs ou les
opérateurs surchargés ne peuvent pas renvoyer un code de retour.
En général, je crois qu'il y a trois types d'erreur :
-- Les erreurs « attendues ». Dans un certain sens, ce ne sont
pas des erreurs, puisqu'on s'y attend, ou qu'on doit s'y
attendre. Ou plutôt, elles sont des erreurs de la part de
l'utilisateur : des fautes de frappe en entrée, par exemple.
En général, traiter ces erreurs doit faire partie de
l'« algorithme », ce qui fait que la meilleur façon de les
annoncer, c'est par un code de retour.
-- Les erreurs « exceptionnelles ». Ce sont des erreurs
auxquelles on ne s'attend pas normalement, mais qu'on sait
peuvent arriver, et qu'on peut vouloir traiter, mais à un
niveau plus élevé, loin d'où l'erreur est detectée. Ce sont
les erreurs pour lesquelles les exceptions conviennent.
-- Les erreurs « impossible ». Ce sont des erreurs qui ne
peuvent pas arriver, tant que le hardware marche et qu'il
n'y a pas d'erreur dans le code. Une violation d'un
invariant, par exemple, ou une faute de parité mémoire
(panne ou défaillance hardware). En général, devant de
telles erreurs, on ne peut rien, et il faut mieux avorter le
programme le plus vite possible.
Mais une telle classification (encore si généralement reconnu
par les experts) est assez catégorique. D'une part, selon
l'application, la même erreur peut être considérer dans une
catégorie ou dans une autre -- considérons un serveur LDAP, qui
traite des requêtes arbitraires formulées en ASN.1, avec un
parseur à déscent récursif pour les interprêter. Comment
catégoriser un débordement de pile dans le parseur Logiquement,
selon la description ci-dessus, c'est une erreur à laquelle il
faut s'y attendre, puisqu'il faut s'attendre à tout d'un
utilisateur. Pratiquement, en revanche, le seul traitement
possible, c'est d'avorter la requête entière, c-à-d de le
traiter à un niveau bien plus élevé dans la pile d'appels, ce
qui argue très fortement pour une exception. Et dans bien des
cas, pratiquement, on ne va pas pouvoir le detecter, même si
elle se produit, parce qu'on ne sait pas (au niveau C++)
détecter un débordement de pile -- du coup, elle devient
« impossible » (et dans la pratique, sous Windows ou Unix, fera
avorter le programme).
Et il y a des considérations très pragmatiques aussi dans
certains cas. Des fonctions comme les constructeurs ou les
opérateurs surchargés ne peuvent pas renvoyer un code de retour.
James Kanze a écrit :
> En général, je crois qu'il y a trois types d'erreur :
> -- Les erreurs « attendues ». Dans un certain sens, ce ne sont
> pas des erreurs, puisqu'on s'y attend, ou qu'on doit s'y
> attendre. Ou plutôt, elles sont des erreurs de la part de
> l'utilisateur : des fautes de frappe en entrée, par exemple.
> En général, traiter ces erreurs doit faire partie de
> l'« algorithme », ce qui fait que la meilleur façon de les
> annoncer, c'est par un code de retour.
je suis d'accord mais cela n'exclut pas un traitement local
par exception.
tu indiquais dans un autre post (ce ne sont pas tes mots
exacts mais ce n'est pas important je pense) que le traitement
par exceptions a tendance à être fait à distance de la source
de l'erreur; il n'y a aucun obligation à cela;
on peut par exemple imaginer un parser (traitant d'une ligne
fichier ou d'une saisie utilisateur) qui s'interromprait par
exception et retournerait une erreur unique, ceci afin de
simplifier l'écriture du code de sortie. eg.
int foo(string const& input){
try {
int x1, x2, ...;
input >> x1;
if (!(condition on x1))
throw 1;
input >> x2;
if (!(condition on x2))
throw 2;
...
}
catch (EOFReached eof){
// clean-up, logs, ...
return NN;
}
catch (int err){
// clean-up relevant for all errors, logs, ...
return err;
}
return 0;
}
> -- Les erreurs « exceptionnelles ». Ce sont des erreurs
> auxquelles on ne s'attend pas normalement, mais qu'on sait
> peuvent arriver, et qu'on peut vouloir traiter, mais à un
> niveau plus élevé, loin d'où l'erreur est detectée. Ce sont
> les erreurs pour lesquelles les exceptions conviennent.
tu mêles deux aspects AMA, le fait que l'erreur soit de faible
probabilité et le fait que son traitement ne soit possible
qu'à un niveau plus élevé.
sur un OS moderne swappant à loisir, je ne m'attends pas à ce
qu'un new échoue par manque de mémoire, pourtant je vais le
tester au plus prêt; d'un autre coté, il y a en effet des
opérations (des séquences) dont le rollback ne peut être fait
qu'en amont (qu'à un niveau assez haut) .
> -- Les erreurs « impossible ». Ce sont des erreurs qui ne
> peuvent pas arriver, tant que le hardware marche et qu'il
> n'y a pas d'erreur dans le code. Une violation d'un
> invariant, par exemple, ou une faute de parité mémoire
> (panne ou défaillance hardware). En général, devant de
> telles erreurs, on ne peut rien, et il faut mieux avorter le
> programme le plus vite possible.
tu dis bien "en général", il reste des cas où des erreurs de ce
type (on parlait des VMError, pas spécifiquement de plantes
matérielles irrécupérables) peuvent et doivent être traitées
(par exemple une stack overflow).
James Kanze a écrit :
> En général, je crois qu'il y a trois types d'erreur :
> -- Les erreurs « attendues ». Dans un certain sens, ce ne sont
> pas des erreurs, puisqu'on s'y attend, ou qu'on doit s'y
> attendre. Ou plutôt, elles sont des erreurs de la part de
> l'utilisateur : des fautes de frappe en entrée, par exemple.
> En général, traiter ces erreurs doit faire partie de
> l'« algorithme », ce qui fait que la meilleur façon de les
> annoncer, c'est par un code de retour.
je suis d'accord mais cela n'exclut pas un traitement local
par exception.
tu indiquais dans un autre post (ce ne sont pas tes mots
exacts mais ce n'est pas important je pense) que le traitement
par exceptions a tendance à être fait à distance de la source
de l'erreur; il n'y a aucun obligation à cela;
on peut par exemple imaginer un parser (traitant d'une ligne
fichier ou d'une saisie utilisateur) qui s'interromprait par
exception et retournerait une erreur unique, ceci afin de
simplifier l'écriture du code de sortie. eg.
int foo(string const& input){
try {
int x1, x2, ...;
input >> x1;
if (!(condition on x1))
throw 1;
input >> x2;
if (!(condition on x2))
throw 2;
...
}
catch (EOFReached eof){
// clean-up, logs, ...
return NN;
}
catch (int err){
// clean-up relevant for all errors, logs, ...
return err;
}
return 0;
}
> -- Les erreurs « exceptionnelles ». Ce sont des erreurs
> auxquelles on ne s'attend pas normalement, mais qu'on sait
> peuvent arriver, et qu'on peut vouloir traiter, mais à un
> niveau plus élevé, loin d'où l'erreur est detectée. Ce sont
> les erreurs pour lesquelles les exceptions conviennent.
tu mêles deux aspects AMA, le fait que l'erreur soit de faible
probabilité et le fait que son traitement ne soit possible
qu'à un niveau plus élevé.
sur un OS moderne swappant à loisir, je ne m'attends pas à ce
qu'un new échoue par manque de mémoire, pourtant je vais le
tester au plus prêt; d'un autre coté, il y a en effet des
opérations (des séquences) dont le rollback ne peut être fait
qu'en amont (qu'à un niveau assez haut) .
> -- Les erreurs « impossible ». Ce sont des erreurs qui ne
> peuvent pas arriver, tant que le hardware marche et qu'il
> n'y a pas d'erreur dans le code. Une violation d'un
> invariant, par exemple, ou une faute de parité mémoire
> (panne ou défaillance hardware). En général, devant de
> telles erreurs, on ne peut rien, et il faut mieux avorter le
> programme le plus vite possible.
tu dis bien "en général", il reste des cas où des erreurs de ce
type (on parlait des VMError, pas spécifiquement de plantes
matérielles irrécupérables) peuvent et doivent être traitées
(par exemple une stack overflow).
James Kanze a écrit :
> En général, je crois qu'il y a trois types d'erreur :
> -- Les erreurs « attendues ». Dans un certain sens, ce ne sont
> pas des erreurs, puisqu'on s'y attend, ou qu'on doit s'y
> attendre. Ou plutôt, elles sont des erreurs de la part de
> l'utilisateur : des fautes de frappe en entrée, par exemple.
> En général, traiter ces erreurs doit faire partie de
> l'« algorithme », ce qui fait que la meilleur façon de les
> annoncer, c'est par un code de retour.
je suis d'accord mais cela n'exclut pas un traitement local
par exception.
tu indiquais dans un autre post (ce ne sont pas tes mots
exacts mais ce n'est pas important je pense) que le traitement
par exceptions a tendance à être fait à distance de la source
de l'erreur; il n'y a aucun obligation à cela;
on peut par exemple imaginer un parser (traitant d'une ligne
fichier ou d'une saisie utilisateur) qui s'interromprait par
exception et retournerait une erreur unique, ceci afin de
simplifier l'écriture du code de sortie. eg.
int foo(string const& input){
try {
int x1, x2, ...;
input >> x1;
if (!(condition on x1))
throw 1;
input >> x2;
if (!(condition on x2))
throw 2;
...
}
catch (EOFReached eof){
// clean-up, logs, ...
return NN;
}
catch (int err){
// clean-up relevant for all errors, logs, ...
return err;
}
return 0;
}
> -- Les erreurs « exceptionnelles ». Ce sont des erreurs
> auxquelles on ne s'attend pas normalement, mais qu'on sait
> peuvent arriver, et qu'on peut vouloir traiter, mais à un
> niveau plus élevé, loin d'où l'erreur est detectée. Ce sont
> les erreurs pour lesquelles les exceptions conviennent.
tu mêles deux aspects AMA, le fait que l'erreur soit de faible
probabilité et le fait que son traitement ne soit possible
qu'à un niveau plus élevé.
sur un OS moderne swappant à loisir, je ne m'attends pas à ce
qu'un new échoue par manque de mémoire, pourtant je vais le
tester au plus prêt; d'un autre coté, il y a en effet des
opérations (des séquences) dont le rollback ne peut être fait
qu'en amont (qu'à un niveau assez haut) .
> -- Les erreurs « impossible ». Ce sont des erreurs qui ne
> peuvent pas arriver, tant que le hardware marche et qu'il
> n'y a pas d'erreur dans le code. Une violation d'un
> invariant, par exemple, ou une faute de parité mémoire
> (panne ou défaillance hardware). En général, devant de
> telles erreurs, on ne peut rien, et il faut mieux avorter le
> programme le plus vite possible.
tu dis bien "en général", il reste des cas où des erreurs de ce
type (on parlait des VMError, pas spécifiquement de plantes
matérielles irrécupérables) peuvent et doivent être traitées
(par exemple une stack overflow).
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.
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.
On 6 juil, 10:24, James Kanze <james.ka...@gmail.com> wrote:
> On Jul 5, 7:01 pm, Gabriel Dos Reis <g...@cs.tamu.edu> wrote:
> > James Kanze <james.ka...@gmail.com> 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.
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.
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.
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.
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.
>>> 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".
>>> 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.
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" !
> 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...
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.
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.
>>> 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".
>>> 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.
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" !
> 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...
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.
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.
>>> 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".
>>> 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.
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" !
> 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...
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.
Michael Doubez a écrit :
Votre discussion à tous deux est intéressante mais vous
m'excuserez de jouer les trouble-fêtes car si le logiciel en
question est du guidage de missile ou du pilotage de module
lunaire ou martien, le printf("oh zut, ça a foiré") suivi de
return(ERROR) me paraît un peu léger :-)
Michael Doubez a écrit :
Votre discussion à tous deux est intéressante mais vous
m'excuserez de jouer les trouble-fêtes car si le logiciel en
question est du guidage de missile ou du pilotage de module
lunaire ou martien, le printf("oh zut, ça a foiré") suivi de
return(ERROR) me paraît un peu léger :-)
Michael Doubez a écrit :
Votre discussion à tous deux est intéressante mais vous
m'excuserez de jouer les trouble-fêtes car si le logiciel en
question est du guidage de missile ou du pilotage de module
lunaire ou martien, le printf("oh zut, ça a foiré") suivi de
return(ERROR) me paraît un peu léger :-)
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, les
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".
On 5 juil, 12:07, James Kanze <james.ka...@gmail.com> wrote:
> On Jul 4, 12:34 pm, "Guillaume Gourdin" <tr...@hotmail.com> 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, les
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".
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, les
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".