D'ailleurs tous les langages "modernes" ont une syntaxe pour
le traitement des exceptions.
D'ailleurs tous les langages "modernes" ont une syntaxe pour
le traitement des exceptions.
D'ailleurs tous les langages "modernes" ont une syntaxe pour
le traitement des exceptions.
Et il savoir apprécier le cas où un code d'erreur de retour est
préférable à une exception.
Désolé mais ton message est incompréhensible.
Et il savoir apprécier le cas où un code d'erreur de retour est
préférable à une exception.
Désolé mais ton message est incompréhensible.
Et il savoir apprécier le cas où un code d'erreur de retour est
préférable à une exception.
Désolé mais ton message est incompréhensible.
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 <wykaaa@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 ?
Elles
apportent en revanche leurs propres problèmes (cherche
« exception safety » sur la toile)
Elles
apportent en revanche leurs propres problèmes (cherche
« exception safety » sur la toile)
Elles
apportent en revanche leurs propres problèmes (cherche
« exception safety » sur la toile)
Elles
apportent en revanche leurs propres problèmes (cherche
« exception safety » sur la toile)
Elles
apportent en revanche leurs propres problèmes (cherche
« exception safety » sur la toile)
Elles
apportent en revanche leurs propres problèmes (cherche
« exception safety » sur la toile)
On Jul 4, 4:22 pm, Wykaaa wrote:Fabien LE LEZ a écrit :On Sat, 4 Jul 2009 12:34:35 +0200, "Guillaume Gourdin" :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.Il y a plusieurs raisons à ça :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.
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.)
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.
En ce qui concerne badbit (erreur dur, erreur d'écriture en
sortie, erreur de lecture physique en entrée), on pourrait en
discuter. Ce genre d'erreur doit être exceptionnelle, et je
crois que l'utilisation d'une exception pourrait se justifier
dans ce cas-là. Mais certainement pas dans les autres cas.
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
}
Même si c'est directement la fonction appelante qui traite
l'exception, il est préférable d'utiliser le mécanisme
d'exception plutôt qu'un code retour.
Pourquoi ?
Parce que le traitement de l'exception est isolé dans le code
(catch) et non disséminé directement derrière l'appel, ce qui
mélange le cas normal et le cas "exceptionnel".
Sauf qu'il a bien dit qu'on parle des cas où l'« erreur » n'est
pas exceptionnelle, et que justement, on veut le traiter tout de
suite ; la gestion de l'erreur est une partie essentielle de
l'algorithme (si l'algorithme est correct), et il faut
l'analyser comme telle. Le problème avec l'exception ici, c'est
justement qu'il exige qu'on sépare physiquement (textuellement,
puisqu'on parle du code source) la gestion de l'erreur de
l'endroit où elle se produit.
C'est une question de méthodologie, de lisibilité et de
maintenabilité.
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é.)
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.
Ce qui apporte quoi ?
On Jul 4, 4:22 pm, Wykaaa <wyk...@yahoo.fr> wrote:
Fabien LE LEZ a écrit :
On Sat, 4 Jul 2009 12:34:35 +0200, "Guillaume Gourdin" :
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.
Il y a plusieurs raisons à ça :
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.
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.)
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.
En ce qui concerne badbit (erreur dur, erreur d'écriture en
sortie, erreur de lecture physique en entrée), on pourrait en
discuter. Ce genre d'erreur doit être exceptionnelle, et je
crois que l'utilisation d'une exception pourrait se justifier
dans ce cas-là. Mais certainement pas dans les autres cas.
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
}
Même si c'est directement la fonction appelante qui traite
l'exception, il est préférable d'utiliser le mécanisme
d'exception plutôt qu'un code retour.
Pourquoi ?
Parce que le traitement de l'exception est isolé dans le code
(catch) et non disséminé directement derrière l'appel, ce qui
mélange le cas normal et le cas "exceptionnel".
Sauf qu'il a bien dit qu'on parle des cas où l'« erreur » n'est
pas exceptionnelle, et que justement, on veut le traiter tout de
suite ; la gestion de l'erreur est une partie essentielle de
l'algorithme (si l'algorithme est correct), et il faut
l'analyser comme telle. Le problème avec l'exception ici, c'est
justement qu'il exige qu'on sépare physiquement (textuellement,
puisqu'on parle du code source) la gestion de l'erreur de
l'endroit où elle se produit.
C'est une question de méthodologie, de lisibilité et de
maintenabilité.
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é.)
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.
Ce qui apporte quoi ?
On Jul 4, 4:22 pm, Wykaaa wrote:Fabien LE LEZ a écrit :On Sat, 4 Jul 2009 12:34:35 +0200, "Guillaume Gourdin" :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.Il y a plusieurs raisons à ça :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.
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.)
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.
En ce qui concerne badbit (erreur dur, erreur d'écriture en
sortie, erreur de lecture physique en entrée), on pourrait en
discuter. Ce genre d'erreur doit être exceptionnelle, et je
crois que l'utilisation d'une exception pourrait se justifier
dans ce cas-là. Mais certainement pas dans les autres cas.
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
}
Même si c'est directement la fonction appelante qui traite
l'exception, il est préférable d'utiliser le mécanisme
d'exception plutôt qu'un code retour.
Pourquoi ?
Parce que le traitement de l'exception est isolé dans le code
(catch) et non disséminé directement derrière l'appel, ce qui
mélange le cas normal et le cas "exceptionnel".
Sauf qu'il a bien dit qu'on parle des cas où l'« erreur » n'est
pas exceptionnelle, et que justement, on veut le traiter tout de
suite ; la gestion de l'erreur est une partie essentielle de
l'algorithme (si l'algorithme est correct), et il faut
l'analyser comme telle. Le problème avec l'exception ici, c'est
justement qu'il exige qu'on sépare physiquement (textuellement,
puisqu'on parle du code source) la gestion de l'erreur de
l'endroit où elle se produit.
C'est une question de méthodologie, de lisibilité et de
maintenabilité.
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é.)
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.
Ce qui apporte quoi ?
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".
--
Michael
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".
--
Michael
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".
--
Michael
On 5 juil, 11:41, "Patrick 'Zener' Brunet"
wrote:Bonjour.
"Guillaume Gourdin" a écrit dans le message
de news 4a4f3042$0$30992$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?
En complément aux arguments de Fabien Le Lez, en lisant du code C++
utilisant des exceptions, on voit souvent des choses aussi lourdes que
risquées, qui peuvent donc "discréditer" les exceptions aux yeux de
certains.
Lancer une exception implique de la construire, donc il vaut mieux que cette
partie-là soit garantie.
C'est pour ça qu'il y a la garantie nothrow. Mais dans le cas général,
à moins d'un état grave de manque de mémoire, la construction des
exceptions n'est pas un problème.Il n'est pas rare de voir des exceptions créées par un new, et pour faire
bonne mesure, on insère tout un tas de diagnostics dedans sous forme de
strings...
C'est du code à la Java.Tout ça pour traiter un incident tels qu'un échec d'allocation de mémoire ?
Il doit bien y avoir des gens que ça ennuie...
Je prefère une exception à un NULL à vérifier chaque fois. De toutes
façons, je ne sais pas quoi faire si j'ai plus de mémoire, il y a peux
de chance qu'essayer de nouveau marche. Le mieux est encore de revenir
à un état antérieur qui se prétend capable de gérer la situation.Ensuite, comment passe-t-on cette exception (que "throwe"-t-on) ?
Par adresse, référence ou par copie ?
Pour autant que je sache, on ne peux pas lancer par référence.
Un bonne règle est de lancer par valeur et de catcher par référence
pour éviter le slicing.La copie est plus naturelle, mais elle implique effectivement de copier tout
ça (donc de mouliner intérieurement du new et du delete).
Je ne comprends pas ce que tu veux dire ici.Reste à voir ce qu'on en fait à la fin (le catch).
Si le système d'exceptions est bien fait, d'une part on a une hiérarchie
bien claire permettant de cascader les catch spécifiques et de se passer du
catch-all (sauf pour faire un cleanup intermédiaire suivi d'un rethrow).
Si je catche quelque chose, c'est que j'ai prévu de le traiter et que
personne ne pense pouvoir le faire dans une sosu-couche donc je sais
bien ce que je doit catcher.
Un cas spécial est la racine d'un thread où je fais un catch sur
plusieurs hiérarchies pour reporter l'erreur à l'application.D'expérience, souvent on voit un catch-all avec dedans un printf("oh zut, ça
a foiré") suivi de return(ERROR).
Il y a beaucoup de cas où il est difficile de trouver une façon
gracieuse de gérer l'erreur. S'assurer que l'utilisateur n'a pas perdu
de données et lui donner une idée du diagnostique est un minimum mais
souvent c'est déjà pas mal.Généralement on est bien embêté parce qu'on se tape pour l'occasion une
librairie plus ou moins exotique et on n'a pas trop le temps de creuser son
fonctionnement intime (c'est même ce qu'on veut éviter - on a la pression
bien sûr):
- Pour le détail des causes d'échec possibles, normalement, on regarde les
retours de la fonction appelée, et on fait un switch avec un default...
- Pour une exception, ça peut venir de plus profond et donc c'est assez
obtus. On ne veut pas en oublier une parce que ça conduit à un plantage et
c'est pas vendeur. Et ça peut arriver par la suite avec une nouvelle version
de ladite librairie. D'où le choix du catch-all équivalent du défault...
Il y a plein de façon d'avoir une bibliothèque mal conçue en dehors
des exceptions.
La gestion des exceptions au bord d'une bibliothèque est sujet à
débat. Mon avis est de n'en laisser passer aucunes sauf les exceptions
standard (allocation ...) et sauf si la logique le justifie (throw
dans un constructeur ou assimilé).Et donc le sort de l'exception elle-même, on s'en désintéresse (ce qui en
soi "justifie" le passage par copie, car alors on peut espérer que le
destructeur prenne en charge tout ce qui doit l'être).
Moi j'aime bien les exceptions passées par adresse avec une méthode
Release() dedans, et je n'ai jamais de memory leak avec ça, mais je suis un
cas...
Ce qui est amusant, c'est que l'usage des exceptions devrait permettre de
démonter proprement une tentative d'opération, pour laisser au process
maître une chance de corriger la situation (libérer des ressources par
exemple) et réessayer.
Pour moi c'est plutôt de retourner à un état connu dans un cas
exceptionnel.
Si il s'agit juste de ressayer, alors on est dans une stratégie locale
et une valeur de retour aurait dû être utilisée.Moi j'aime pas trop les logiciels qui disent "au
secours, j'y arrive pas", de plus je fais dans le process automatisé, alors
souvent il n'y a personne pour lire le message.
Un petit mail à l'administrateur, ça fait toujours plaisir :)En général, on va seulement sortir un message "désolé ça a foiré" puis
avorter. Très souvent, la cause précise de l'erreur n'est pas remontée
jusque-là.
Pour faire ça, il faudrait que la nomenclature des erreurs de chaque
sous-librairie soit définie (et figée) et intégrée dans la nomenclature de
la librairie qui l'utilise, etc.
jusqu'au process maître. Il faudrait aussi
pouvoir retourner un contexte assez détaillé dans la même démarche
encyclopédique. Il faudrait ensuite que process maître ait une stratégie
correctrice pour chaque cas recensé.
Je pense que dans ce cas, il y a confusion entre les logs et le
mécanisme d'exception.En général on ne se donne pas cette peine, ou on n'a pas de doc utilisable
pour les insides, et donc la mission de diagnostic détaillé de l'exception
devient presque inutile (tout au plus on ramène le complément du message
d'erreur à afficher pour faire plus humain "erreur système lors de l'accès
à: ujk35585.dat").
Ne reste que la lourdeur apparente du mécanisme d'exception par rapport à un
bon vieux return(code), spécialement si on dispose d'un enum de valeurs
génériques (ou l'équivalent en #define) dans un header global (beuâârk).
Tester chaque retour d'erreur tout en sachant que la probabilité
d'erreur dans une sous-couche dont on est même pas conscient à un
effet déprimant (pour moi). Surtout quand la seule chose que je peux
faire est de prévenir la couche au dessus que ça a pas marché.
L'exception a au moins l'avantage d'automatiser cela.
--
Michael
On 5 juil, 11:41, "Patrick 'Zener' Brunet"
<use.link.in.signat...@ddress.invalid> wrote:
Bonjour.
"Guillaume Gourdin" <tr...@hotmail.com> a écrit dans le message
de news 4a4f3042$0$30992$426a7...@news.free.fr
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?
En complément aux arguments de Fabien Le Lez, en lisant du code C++
utilisant des exceptions, on voit souvent des choses aussi lourdes que
risquées, qui peuvent donc "discréditer" les exceptions aux yeux de
certains.
Lancer une exception implique de la construire, donc il vaut mieux que cette
partie-là soit garantie.
C'est pour ça qu'il y a la garantie nothrow. Mais dans le cas général,
à moins d'un état grave de manque de mémoire, la construction des
exceptions n'est pas un problème.
Il n'est pas rare de voir des exceptions créées par un new, et pour faire
bonne mesure, on insère tout un tas de diagnostics dedans sous forme de
strings...
C'est du code à la Java.
Tout ça pour traiter un incident tels qu'un échec d'allocation de mémoire ?
Il doit bien y avoir des gens que ça ennuie...
Je prefère une exception à un NULL à vérifier chaque fois. De toutes
façons, je ne sais pas quoi faire si j'ai plus de mémoire, il y a peux
de chance qu'essayer de nouveau marche. Le mieux est encore de revenir
à un état antérieur qui se prétend capable de gérer la situation.
Ensuite, comment passe-t-on cette exception (que "throwe"-t-on) ?
Par adresse, référence ou par copie ?
Pour autant que je sache, on ne peux pas lancer par référence.
Un bonne règle est de lancer par valeur et de catcher par référence
pour éviter le slicing.
La copie est plus naturelle, mais elle implique effectivement de copier tout
ça (donc de mouliner intérieurement du new et du delete).
Je ne comprends pas ce que tu veux dire ici.
Reste à voir ce qu'on en fait à la fin (le catch).
Si le système d'exceptions est bien fait, d'une part on a une hiérarchie
bien claire permettant de cascader les catch spécifiques et de se passer du
catch-all (sauf pour faire un cleanup intermédiaire suivi d'un rethrow).
Si je catche quelque chose, c'est que j'ai prévu de le traiter et que
personne ne pense pouvoir le faire dans une sosu-couche donc je sais
bien ce que je doit catcher.
Un cas spécial est la racine d'un thread où je fais un catch sur
plusieurs hiérarchies pour reporter l'erreur à l'application.
D'expérience, souvent on voit un catch-all avec dedans un printf("oh zut, ça
a foiré") suivi de return(ERROR).
Il y a beaucoup de cas où il est difficile de trouver une façon
gracieuse de gérer l'erreur. S'assurer que l'utilisateur n'a pas perdu
de données et lui donner une idée du diagnostique est un minimum mais
souvent c'est déjà pas mal.
Généralement on est bien embêté parce qu'on se tape pour l'occasion une
librairie plus ou moins exotique et on n'a pas trop le temps de creuser son
fonctionnement intime (c'est même ce qu'on veut éviter - on a la pression
bien sûr):
- Pour le détail des causes d'échec possibles, normalement, on regarde les
retours de la fonction appelée, et on fait un switch avec un default...
- Pour une exception, ça peut venir de plus profond et donc c'est assez
obtus. On ne veut pas en oublier une parce que ça conduit à un plantage et
c'est pas vendeur. Et ça peut arriver par la suite avec une nouvelle version
de ladite librairie. D'où le choix du catch-all équivalent du défault...
Il y a plein de façon d'avoir une bibliothèque mal conçue en dehors
des exceptions.
La gestion des exceptions au bord d'une bibliothèque est sujet à
débat. Mon avis est de n'en laisser passer aucunes sauf les exceptions
standard (allocation ...) et sauf si la logique le justifie (throw
dans un constructeur ou assimilé).
Et donc le sort de l'exception elle-même, on s'en désintéresse (ce qui en
soi "justifie" le passage par copie, car alors on peut espérer que le
destructeur prenne en charge tout ce qui doit l'être).
Moi j'aime bien les exceptions passées par adresse avec une méthode
Release() dedans, et je n'ai jamais de memory leak avec ça, mais je suis un
cas...
Ce qui est amusant, c'est que l'usage des exceptions devrait permettre de
démonter proprement une tentative d'opération, pour laisser au process
maître une chance de corriger la situation (libérer des ressources par
exemple) et réessayer.
Pour moi c'est plutôt de retourner à un état connu dans un cas
exceptionnel.
Si il s'agit juste de ressayer, alors on est dans une stratégie locale
et une valeur de retour aurait dû être utilisée.
Moi j'aime pas trop les logiciels qui disent "au
secours, j'y arrive pas", de plus je fais dans le process automatisé, alors
souvent il n'y a personne pour lire le message.
Un petit mail à l'administrateur, ça fait toujours plaisir :)
En général, on va seulement sortir un message "désolé ça a foiré" puis
avorter. Très souvent, la cause précise de l'erreur n'est pas remontée
jusque-là.
Pour faire ça, il faudrait que la nomenclature des erreurs de chaque
sous-librairie soit définie (et figée) et intégrée dans la nomenclature de
la librairie qui l'utilise, etc.
jusqu'au process maître. Il faudrait aussi
pouvoir retourner un contexte assez détaillé dans la même démarche
encyclopédique. Il faudrait ensuite que process maître ait une stratégie
correctrice pour chaque cas recensé.
Je pense que dans ce cas, il y a confusion entre les logs et le
mécanisme d'exception.
En général on ne se donne pas cette peine, ou on n'a pas de doc utilisable
pour les insides, et donc la mission de diagnostic détaillé de l'exception
devient presque inutile (tout au plus on ramène le complément du message
d'erreur à afficher pour faire plus humain "erreur système lors de l'accès
à: ujk35585.dat").
Ne reste que la lourdeur apparente du mécanisme d'exception par rapport à un
bon vieux return(code), spécialement si on dispose d'un enum de valeurs
génériques (ou l'équivalent en #define) dans un header global (beuâârk).
Tester chaque retour d'erreur tout en sachant que la probabilité
d'erreur dans une sous-couche dont on est même pas conscient à un
effet déprimant (pour moi). Surtout quand la seule chose que je peux
faire est de prévenir la couche au dessus que ça a pas marché.
L'exception a au moins l'avantage d'automatiser cela.
--
Michael
On 5 juil, 11:41, "Patrick 'Zener' Brunet"
wrote:Bonjour.
"Guillaume Gourdin" a écrit dans le message
de news 4a4f3042$0$30992$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?
En complément aux arguments de Fabien Le Lez, en lisant du code C++
utilisant des exceptions, on voit souvent des choses aussi lourdes que
risquées, qui peuvent donc "discréditer" les exceptions aux yeux de
certains.
Lancer une exception implique de la construire, donc il vaut mieux que cette
partie-là soit garantie.
C'est pour ça qu'il y a la garantie nothrow. Mais dans le cas général,
à moins d'un état grave de manque de mémoire, la construction des
exceptions n'est pas un problème.Il n'est pas rare de voir des exceptions créées par un new, et pour faire
bonne mesure, on insère tout un tas de diagnostics dedans sous forme de
strings...
C'est du code à la Java.Tout ça pour traiter un incident tels qu'un échec d'allocation de mémoire ?
Il doit bien y avoir des gens que ça ennuie...
Je prefère une exception à un NULL à vérifier chaque fois. De toutes
façons, je ne sais pas quoi faire si j'ai plus de mémoire, il y a peux
de chance qu'essayer de nouveau marche. Le mieux est encore de revenir
à un état antérieur qui se prétend capable de gérer la situation.Ensuite, comment passe-t-on cette exception (que "throwe"-t-on) ?
Par adresse, référence ou par copie ?
Pour autant que je sache, on ne peux pas lancer par référence.
Un bonne règle est de lancer par valeur et de catcher par référence
pour éviter le slicing.La copie est plus naturelle, mais elle implique effectivement de copier tout
ça (donc de mouliner intérieurement du new et du delete).
Je ne comprends pas ce que tu veux dire ici.Reste à voir ce qu'on en fait à la fin (le catch).
Si le système d'exceptions est bien fait, d'une part on a une hiérarchie
bien claire permettant de cascader les catch spécifiques et de se passer du
catch-all (sauf pour faire un cleanup intermédiaire suivi d'un rethrow).
Si je catche quelque chose, c'est que j'ai prévu de le traiter et que
personne ne pense pouvoir le faire dans une sosu-couche donc je sais
bien ce que je doit catcher.
Un cas spécial est la racine d'un thread où je fais un catch sur
plusieurs hiérarchies pour reporter l'erreur à l'application.D'expérience, souvent on voit un catch-all avec dedans un printf("oh zut, ça
a foiré") suivi de return(ERROR).
Il y a beaucoup de cas où il est difficile de trouver une façon
gracieuse de gérer l'erreur. S'assurer que l'utilisateur n'a pas perdu
de données et lui donner une idée du diagnostique est un minimum mais
souvent c'est déjà pas mal.Généralement on est bien embêté parce qu'on se tape pour l'occasion une
librairie plus ou moins exotique et on n'a pas trop le temps de creuser son
fonctionnement intime (c'est même ce qu'on veut éviter - on a la pression
bien sûr):
- Pour le détail des causes d'échec possibles, normalement, on regarde les
retours de la fonction appelée, et on fait un switch avec un default...
- Pour une exception, ça peut venir de plus profond et donc c'est assez
obtus. On ne veut pas en oublier une parce que ça conduit à un plantage et
c'est pas vendeur. Et ça peut arriver par la suite avec une nouvelle version
de ladite librairie. D'où le choix du catch-all équivalent du défault...
Il y a plein de façon d'avoir une bibliothèque mal conçue en dehors
des exceptions.
La gestion des exceptions au bord d'une bibliothèque est sujet à
débat. Mon avis est de n'en laisser passer aucunes sauf les exceptions
standard (allocation ...) et sauf si la logique le justifie (throw
dans un constructeur ou assimilé).Et donc le sort de l'exception elle-même, on s'en désintéresse (ce qui en
soi "justifie" le passage par copie, car alors on peut espérer que le
destructeur prenne en charge tout ce qui doit l'être).
Moi j'aime bien les exceptions passées par adresse avec une méthode
Release() dedans, et je n'ai jamais de memory leak avec ça, mais je suis un
cas...
Ce qui est amusant, c'est que l'usage des exceptions devrait permettre de
démonter proprement une tentative d'opération, pour laisser au process
maître une chance de corriger la situation (libérer des ressources par
exemple) et réessayer.
Pour moi c'est plutôt de retourner à un état connu dans un cas
exceptionnel.
Si il s'agit juste de ressayer, alors on est dans une stratégie locale
et une valeur de retour aurait dû être utilisée.Moi j'aime pas trop les logiciels qui disent "au
secours, j'y arrive pas", de plus je fais dans le process automatisé, alors
souvent il n'y a personne pour lire le message.
Un petit mail à l'administrateur, ça fait toujours plaisir :)En général, on va seulement sortir un message "désolé ça a foiré" puis
avorter. Très souvent, la cause précise de l'erreur n'est pas remontée
jusque-là.
Pour faire ça, il faudrait que la nomenclature des erreurs de chaque
sous-librairie soit définie (et figée) et intégrée dans la nomenclature de
la librairie qui l'utilise, etc.
jusqu'au process maître. Il faudrait aussi
pouvoir retourner un contexte assez détaillé dans la même démarche
encyclopédique. Il faudrait ensuite que process maître ait une stratégie
correctrice pour chaque cas recensé.
Je pense que dans ce cas, il y a confusion entre les logs et le
mécanisme d'exception.En général on ne se donne pas cette peine, ou on n'a pas de doc utilisable
pour les insides, et donc la mission de diagnostic détaillé de l'exception
devient presque inutile (tout au plus on ramène le complément du message
d'erreur à afficher pour faire plus humain "erreur système lors de l'accès
à: ujk35585.dat").
Ne reste que la lourdeur apparente du mécanisme d'exception par rapport à un
bon vieux return(code), spécialement si on dispose d'un enum de valeurs
génériques (ou l'équivalent en #define) dans un header global (beuâârk).
Tester chaque retour d'erreur tout en sachant que la probabilité
d'erreur dans une sous-couche dont on est même pas conscient à un
effet déprimant (pour moi). Surtout quand la seule chose que je peux
faire est de prévenir la couche au dessus que ça a pas marché.
L'exception a au moins l'avantage d'automatiser cela.
--
Michael
Votre discussion à tous deux est intéressante mais vous m'excuserez d e
jouer les trouble-fêtes car si le logiciel en question est du guidage d e
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 :-)
Votre discussion à tous deux est intéressante mais vous m'excuserez d e
jouer les trouble-fêtes car si le logiciel en question est du guidage d e
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 :-)
Votre discussion à tous deux est intéressante mais vous m'excuserez d e
jouer les trouble-fêtes car si le logiciel en question est du guidage d e
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 :
> 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".
Ce qui me semble un bon usage.
Michael Doubez a écrit :
> 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, 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".
Ce qui me semble un bon usage.
Michael Doubez a écrit :
> 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".
Ce qui me semble un bon usage.