Bonjour,
Je débute et j'ai un peu de mal a gérer une exception...J'aimerais faire
renvoyer un résultat ou un code d'erreur a la fonction si le calcul échoue.
Je pourrais renvoyer le résultat dans un argument par réference... mais
compte tenu de mes besoins cela suffit. Le code d'erreur que ma fonction
doit renvoyer est -1 en cas d'échec. Je prend l'exemple de la fonction
suivante:
dans la console cout << Division(3, 2) << endl renvoie 1.5 cout << Division(3, 0) << endl renvoie 1.#INF
Pourquoi ne puis je pas affecter la valeur -1 a Tmp dans le bloc catch?..
parce que le code n'entre PAS dans le catch (le coproc arith. ne lève pas d'exception tout seul, même si ...) une exécution en debug pas à pas l'aurait montré.
dans la console
cout << Division(3, 2) << endl renvoie 1.5
cout << Division(3, 0) << endl renvoie 1.#INF
Pourquoi ne puis je pas affecter la valeur -1 a Tmp dans le bloc catch?..
parce que le code n'entre PAS dans le catch (le coproc arith. ne lève
pas d'exception tout seul, même si ...)
une exécution en debug pas à pas l'aurait montré.
dans la console cout << Division(3, 2) << endl renvoie 1.5 cout << Division(3, 0) << endl renvoie 1.#INF
Pourquoi ne puis je pas affecter la valeur -1 a Tmp dans le bloc catch?..
parce que le code n'entre PAS dans le catch (le coproc arith. ne lève pas d'exception tout seul, même si ...) une exécution en debug pas à pas l'aurait montré.
Sylvain.
Mathias Gaunard
Bonjour, Je débute et j'ai un peu de mal a gérer une exception...
try { Tmp = a/b; }
Aucune exception n'est jamais levée dans ton bloc try. Une exception est levée par l'instruction throw et par celle-ci uniquement.
double Division(double a, double b) { if(b != 0.0) // éventuellement à affiner car ce sont des doubles? return a/b;
return -1.0; }
Après, je ne trouve pas cela particulièrement pertinent de définir x/0 comme étant -1... Du coup, toute division ayant pour résultat -1 est considérée comme une erreur : super.
En fait pour ton problème, tu as trois solutions : utiliser le fait que les doubles ont des représentations particulières pour les résultats invalides, lever une exception en cas de division par zéro, ou tout simplement te débrouiller pour que la division par zéro n'arrive jamais, étant plus une erreur de programmation qu'autre chose.
Pourquoi ne puis je pas affecter la valeur -1 a Tmp dans le bloc catch?..
Parce que tu ne rentres jamais dans ce bloc ?
Bonjour,
Je débute et j'ai un peu de mal a gérer une exception...
try
{
Tmp = a/b;
}
Aucune exception n'est jamais levée dans ton bloc try.
Une exception est levée par l'instruction throw et par celle-ci uniquement.
double Division(double a, double b)
{
if(b != 0.0) // éventuellement à affiner car ce sont des doubles?
return a/b;
return -1.0;
}
Après, je ne trouve pas cela particulièrement pertinent de définir x/0
comme étant -1...
Du coup, toute division ayant pour résultat -1 est considérée comme une
erreur : super.
En fait pour ton problème, tu as trois solutions : utiliser le fait que
les doubles ont des représentations particulières pour les résultats
invalides, lever une exception en cas de division par zéro, ou tout
simplement te débrouiller pour que la division par zéro n'arrive jamais,
étant plus une erreur de programmation qu'autre chose.
Pourquoi ne puis je pas affecter la valeur -1 a Tmp dans le bloc catch?..
Bonjour, Je débute et j'ai un peu de mal a gérer une exception...
try { Tmp = a/b; }
Aucune exception n'est jamais levée dans ton bloc try. Une exception est levée par l'instruction throw et par celle-ci uniquement.
double Division(double a, double b) { if(b != 0.0) // éventuellement à affiner car ce sont des doubles? return a/b;
return -1.0; }
Après, je ne trouve pas cela particulièrement pertinent de définir x/0 comme étant -1... Du coup, toute division ayant pour résultat -1 est considérée comme une erreur : super.
En fait pour ton problème, tu as trois solutions : utiliser le fait que les doubles ont des représentations particulières pour les résultats invalides, lever une exception en cas de division par zéro, ou tout simplement te débrouiller pour que la division par zéro n'arrive jamais, étant plus une erreur de programmation qu'autre chose.
Pourquoi ne puis je pas affecter la valeur -1 a Tmp dans le bloc catch?..
Parce que tu ne rentres jamais dans ce bloc ?
Xavier
Merci a tous deux pour vos réponses. Je crois que j'ai pas du comprendre grand chose a la génération/réception d'une exeption (je pensais qu'une exception était levé par une erreur qui renvoyait alors vers le bloc catch...). Bon je sais que l'exemple Division par zero n'etait pas judicieux (il faut le prendre pour un exemple pour illustrer le fonctionnement de ma fonction). Pour tout dire la fonction qui me pose "probleme" est un peu plus complexe (une dizaine d'argument que l'utilisateur) et pour ne pas gérer les arguments entrants avec des if (ce que je ferais quand même a terme), je voulais pouvoir récuperer un résultat sans faire planter le systeme... Je vais me replonger dans les exceptions ... Xavier
Merci a tous deux pour vos réponses. Je crois que j'ai pas du comprendre
grand chose a la génération/réception d'une exeption (je pensais qu'une
exception était levé par une erreur qui renvoyait alors vers le bloc
catch...).
Bon je sais que l'exemple Division par zero n'etait pas judicieux (il faut
le prendre pour un exemple pour illustrer le fonctionnement de ma fonction).
Pour tout dire la fonction qui me pose "probleme" est un peu plus complexe
(une dizaine d'argument que l'utilisateur) et pour ne pas gérer les
arguments entrants avec des if (ce que je ferais quand même a terme), je
voulais pouvoir récuperer un résultat sans faire planter le systeme...
Je vais me replonger dans les exceptions ...
Xavier
Merci a tous deux pour vos réponses. Je crois que j'ai pas du comprendre grand chose a la génération/réception d'une exeption (je pensais qu'une exception était levé par une erreur qui renvoyait alors vers le bloc catch...). Bon je sais que l'exemple Division par zero n'etait pas judicieux (il faut le prendre pour un exemple pour illustrer le fonctionnement de ma fonction). Pour tout dire la fonction qui me pose "probleme" est un peu plus complexe (une dizaine d'argument que l'utilisateur) et pour ne pas gérer les arguments entrants avec des if (ce que je ferais quand même a terme), je voulais pouvoir récuperer un résultat sans faire planter le systeme... Je vais me replonger dans les exceptions ... Xavier
Sylvain
Xavier wrote on 03/04/2007 18:28:
Merci a tous deux pour vos réponses. Je crois que j'ai pas du comprendre grand chose a la génération/réception d'une exeption (je pensais qu'une exception était levé par une erreur qui renvoyait alors vers le bloc catch...).
ton code gère correctement la réception d'exception mais pas la levée.
aucune opération élémentaire ne génère elle-même une exception, c'est le code que tu écris, ou les librairies utilisées, qui lève explicitement une exception.
note également que (quasiment) tout peux servir d'arguments d'exception, selon ce que tu lèves, ou ce que des libs tierces lèvent, tu devras fournir les handlers (récepteurs) d'exception correspondant.
au passage, les exceptions peuvent bien surs être chainée, sans en répercutant l'argument reçu (syntaxe "throw") sans en levant une nouvelle exception.
exemple:
double Division(double a, double b){ try { try { if (b == 1.0) throw "ça va pas changer grand chose"; if (b == 0.0) throw (double) -1.0; return a / b; } catch (const char* msg){ cout << msg << endl; throw (double) a; } catch (double value){ throw; // relève une exception avec value } } catch (double resultCode){ return resultCode; } }
Sylvain.
Xavier wrote on 03/04/2007 18:28:
Merci a tous deux pour vos réponses. Je crois que j'ai pas du comprendre
grand chose a la génération/réception d'une exeption (je pensais qu'une
exception était levé par une erreur qui renvoyait alors vers le bloc
catch...).
ton code gère correctement la réception d'exception mais pas la levée.
aucune opération élémentaire ne génère elle-même une exception, c'est le
code que tu écris, ou les librairies utilisées, qui lève explicitement
une exception.
note également que (quasiment) tout peux servir d'arguments d'exception,
selon ce que tu lèves, ou ce que des libs tierces lèvent, tu devras
fournir les handlers (récepteurs) d'exception correspondant.
au passage, les exceptions peuvent bien surs être chainée, sans en
répercutant l'argument reçu (syntaxe "throw") sans en levant une
nouvelle exception.
exemple:
double Division(double a, double b){
try {
try {
if (b == 1.0)
throw "ça va pas changer grand chose";
if (b == 0.0)
throw (double) -1.0;
return a / b;
}
catch (const char* msg){
cout << msg << endl;
throw (double) a;
}
catch (double value){
throw; // relève une exception avec value
}
}
catch (double resultCode){
return resultCode;
}
}
Merci a tous deux pour vos réponses. Je crois que j'ai pas du comprendre grand chose a la génération/réception d'une exeption (je pensais qu'une exception était levé par une erreur qui renvoyait alors vers le bloc catch...).
ton code gère correctement la réception d'exception mais pas la levée.
aucune opération élémentaire ne génère elle-même une exception, c'est le code que tu écris, ou les librairies utilisées, qui lève explicitement une exception.
note également que (quasiment) tout peux servir d'arguments d'exception, selon ce que tu lèves, ou ce que des libs tierces lèvent, tu devras fournir les handlers (récepteurs) d'exception correspondant.
au passage, les exceptions peuvent bien surs être chainée, sans en répercutant l'argument reçu (syntaxe "throw") sans en levant une nouvelle exception.
exemple:
double Division(double a, double b){ try { try { if (b == 1.0) throw "ça va pas changer grand chose"; if (b == 0.0) throw (double) -1.0; return a / b; } catch (const char* msg){ cout << msg << endl; throw (double) a; } catch (double value){ throw; // relève une exception avec value } } catch (double resultCode){ return resultCode; } }
Sylvain.
Xavier
Merci sylvain pour tes explications. Je commence a saisir la logique. Je crois que je dois encore approfondir pour saisir tout l'interet des exceptions. Mais les brumes commencent a se lever..
note également que (quasiment) tout peux servir d'arguments d'exception, selon ce que tu lèves, ou ce que des libs tierces lèvent, tu devras fournir les handlers (récepteurs) d'exception correspondant.
au passage, les exceptions peuvent bien surs être chainée, sans en répercutant l'argument reçu (syntaxe "throw") sans en levant une nouvelle exception.
exemple:
double Division(double a, double b){ try { try { if (b == 1.0) throw "ça va pas changer grand chose"; if (b == 0.0) throw (double) -1.0; return a / b; } catch (const char* msg){ cout << msg << endl; throw (double) a; } catch (double value){ throw; // relève une exception avec value Je ne comprend pas bien ce que fait le throw ici (sans argument) ?
Merci sylvain pour tes explications. Je commence a saisir la logique. Je
crois que je dois encore approfondir pour saisir tout l'interet des
exceptions. Mais les brumes commencent a se lever..
note également que (quasiment) tout peux servir d'arguments d'exception,
selon ce que tu lèves, ou ce que des libs tierces lèvent, tu devras
fournir les handlers (récepteurs) d'exception correspondant.
au passage, les exceptions peuvent bien surs être chainée, sans en
répercutant l'argument reçu (syntaxe "throw") sans en levant une nouvelle
exception.
exemple:
double Division(double a, double b){
try {
try {
if (b == 1.0)
throw "ça va pas changer grand chose";
if (b == 0.0)
throw (double) -1.0;
return a / b;
}
catch (const char* msg){
cout << msg << endl;
throw (double) a;
}
catch (double value){
throw; // relève une exception avec value
Je ne comprend pas bien ce que fait le throw ici (sans argument) ?
Merci sylvain pour tes explications. Je commence a saisir la logique. Je crois que je dois encore approfondir pour saisir tout l'interet des exceptions. Mais les brumes commencent a se lever..
note également que (quasiment) tout peux servir d'arguments d'exception, selon ce que tu lèves, ou ce que des libs tierces lèvent, tu devras fournir les handlers (récepteurs) d'exception correspondant.
au passage, les exceptions peuvent bien surs être chainée, sans en répercutant l'argument reçu (syntaxe "throw") sans en levant une nouvelle exception.
exemple:
double Division(double a, double b){ try { try { if (b == 1.0) throw "ça va pas changer grand chose"; if (b == 0.0) throw (double) -1.0; return a / b; } catch (const char* msg){ cout << msg << endl; throw (double) a; } catch (double value){ throw; // relève une exception avec value Je ne comprend pas bien ce que fait le throw ici (sans argument) ?
double Division(double a, double b){ try { try { if (b == 0.0) lève une exception ""de type"" double
(je n'aime pas cette formule mais à défaut)
throw (double) -1.0; return a / b; } catch (double value){ on attrape ici puisque ""l'on a lancé"" un double
et on "re-throw" l'argument (donc un double valant 'value')
throw; // relève une exception avec value
Je ne comprend pas bien ce que fait le throw ici (sans argument) ?
} } catch (double resultCode){ le "throw" nous amène ici puisque un ""double a été lancé""
return resultCode; } }
re-thrower (ou "throw" sans argument) peut être utile pour faire le ménage en cascade, par exemple:
Bar* bar = null;
try { bar = new Bar(); if (!bar->f()) throw "f is not verified"; // jump to handler1
Foo* foo = null; try { foo = new Foo(); if (!foo->g()) throw "g is not verified"; // jump to handler2 } catch (...){ // handler2, catch all exceptions if (foo) delete foo; // cascade l'exception (quelle que soit puisque "...") throw; // follow clean-up, jump to handler1 } } catch (const char* reason){ // handler1 if (bar) delete bar; return errorCode; }
(la gestion des allocations ne sert qu'à illustrer les exceptions, elle ne se justifie pas en soi).
Sylvain.
Xavier
Merci pour l'explication Sylvain. (j'aurai pu potasser un peu la littérature pour le "throw;") Xavier "Sylvain" a écrit dans le message de news: 4612a5d4$0$27399$
Xavier wrote on 03/04/2007 19:23:
double Division(double a, double b){ try { try { if (b == 0.0) lève une exception ""de type"" double
(je n'aime pas cette formule mais à défaut)
throw (double) -1.0; return a / b; } catch (double value){ on attrape ici puisque ""l'on a lancé"" un double
et on "re-throw" l'argument (donc un double valant 'value')
throw; // relève une exception avec value
Je ne comprend pas bien ce que fait le throw ici (sans argument) ?
} } catch (double resultCode){ le "throw" nous amène ici puisque un ""double a été lancé""
return resultCode; } }
re-thrower (ou "throw" sans argument) peut être utile pour faire le ménage en cascade, par exemple:
Bar* bar = null;
try { bar = new Bar(); if (!bar->f()) throw "f is not verified"; // jump to handler1
Foo* foo = null; try { foo = new Foo(); if (!foo->g()) throw "g is not verified"; // jump to handler2 } catch (...){ // handler2, catch all exceptions if (foo) delete foo; // cascade l'exception (quelle que soit puisque "...") throw; // follow clean-up, jump to handler1 } } catch (const char* reason){ // handler1 if (bar) delete bar; return errorCode; }
(la gestion des allocations ne sert qu'à illustrer les exceptions, elle ne se justifie pas en soi).
Sylvain.
Merci pour l'explication Sylvain. (j'aurai pu potasser un peu la littérature
pour le "throw;")
Xavier
"Sylvain" <noSpam@mail.net> a écrit dans le message de news:
4612a5d4$0$27399$ba4acef3@news.orange.fr...
Xavier wrote on 03/04/2007 19:23:
double Division(double a, double b){
try {
try {
if (b == 0.0)
lève une exception ""de type"" double
(je n'aime pas cette formule mais à défaut)
throw (double) -1.0;
return a / b;
}
catch (double value){
on attrape ici puisque ""l'on a lancé"" un double
et on "re-throw" l'argument (donc un double valant 'value')
throw; // relève une exception avec value
Je ne comprend pas bien ce que fait le throw ici (sans argument) ?
}
}
catch (double resultCode){
le "throw" nous amène ici puisque un ""double a été lancé""
return resultCode;
}
}
re-thrower (ou "throw" sans argument) peut être utile pour faire le ménage
en cascade, par exemple:
Bar* bar = null;
try {
bar = new Bar();
if (!bar->f())
throw "f is not verified"; // jump to handler1
Foo* foo = null;
try {
foo = new Foo();
if (!foo->g())
throw "g is not verified"; // jump to handler2
}
catch (...){ // handler2, catch all exceptions
if (foo)
delete foo;
// cascade l'exception (quelle que soit puisque "...")
throw; // follow clean-up, jump to handler1
}
}
catch (const char* reason){ // handler1
if (bar)
delete bar;
return errorCode;
}
(la gestion des allocations ne sert qu'à illustrer les exceptions, elle ne
se justifie pas en soi).
Merci pour l'explication Sylvain. (j'aurai pu potasser un peu la littérature pour le "throw;") Xavier "Sylvain" a écrit dans le message de news: 4612a5d4$0$27399$
Xavier wrote on 03/04/2007 19:23:
double Division(double a, double b){ try { try { if (b == 0.0) lève une exception ""de type"" double
(je n'aime pas cette formule mais à défaut)
throw (double) -1.0; return a / b; } catch (double value){ on attrape ici puisque ""l'on a lancé"" un double
et on "re-throw" l'argument (donc un double valant 'value')
throw; // relève une exception avec value
Je ne comprend pas bien ce que fait le throw ici (sans argument) ?
} } catch (double resultCode){ le "throw" nous amène ici puisque un ""double a été lancé""
return resultCode; } }
re-thrower (ou "throw" sans argument) peut être utile pour faire le ménage en cascade, par exemple:
Bar* bar = null;
try { bar = new Bar(); if (!bar->f()) throw "f is not verified"; // jump to handler1
Foo* foo = null; try { foo = new Foo(); if (!foo->g()) throw "g is not verified"; // jump to handler2 } catch (...){ // handler2, catch all exceptions if (foo) delete foo; // cascade l'exception (quelle que soit puisque "...") throw; // follow clean-up, jump to handler1 } } catch (const char* reason){ // handler1 if (bar) delete bar; return errorCode; }
(la gestion des allocations ne sert qu'à illustrer les exceptions, elle ne se justifie pas en soi).
Sylvain.
James Kanze
On Apr 3, 4:29 pm, Mathias Gaunard wrote:
Je débute et j'ai un peu de mal a gérer une exception... try { Tmp = a/b; }
Aucune exception n'est jamais levée dans ton bloc try.
Ça, on ne peut pas le dire non plus. Il a une division par 0 ; c'est un comportement indéfini, et donc, on ne sait pas ce qui va se passer.
Sur des processeurs qui implémente les flottants IEEE, la division par 0 a un comportement défini, qui est de renvoyer la valeur infini (et non de lever une exception). Sur les autres processeurs que j'ai eu l'occasion d'essayer (et dans le cas de l'arithmetique des entiers sur tous les processeurs), la division par 0 provoque l'arrêt du programme : en fait, il lève un « signal » (non une exception) dont le traitement par défaut est de générer un core dump et de terminer le programme.
Une exception est levée par l'instruction throw et par celle-ci uniquement.
Dans le cas d'un comportement indéfini, tout est possible. Y compris une exception.
double Division(double a, double b) { if(b != 0.0) // éventuellement à affiner car ce sont des doubl es? return a/b;
return -1.0; }
Après, je ne trouve pas cela particulièrement pertinent de définir x/0 comme étant -1...
C'était sans doute à titre d'exemple, et que les conditions d'erreur sont plus complexe dans son code réel.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
On Apr 3, 4:29 pm, Mathias Gaunard <loufo...@gmail.com> wrote:
Je débute et j'ai un peu de mal a gérer une exception...
try
{
Tmp = a/b;
}
Aucune exception n'est jamais levée dans ton bloc try.
Ça, on ne peut pas le dire non plus. Il a une division par 0 ;
c'est un comportement indéfini, et donc, on ne sait pas ce qui
va se passer.
Sur des processeurs qui implémente les flottants IEEE, la
division par 0 a un comportement défini, qui est de renvoyer la
valeur infini (et non de lever une exception). Sur les autres
processeurs que j'ai eu l'occasion d'essayer (et dans le cas de
l'arithmetique des entiers sur tous les processeurs), la
division par 0 provoque l'arrêt du programme : en fait, il lève
un « signal » (non une exception) dont le traitement par
défaut est de générer un core dump et de terminer le programme.
Une exception est levée par l'instruction throw et par
celle-ci uniquement.
Dans le cas d'un comportement indéfini, tout est possible. Y
compris une exception.
double Division(double a, double b)
{
if(b != 0.0) // éventuellement à affiner car ce sont des doubl es?
return a/b;
return -1.0;
}
Après, je ne trouve pas cela particulièrement pertinent de définir x/0
comme étant -1...
C'était sans doute à titre d'exemple, et que les conditions
d'erreur sont plus complexe dans son code réel.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Je débute et j'ai un peu de mal a gérer une exception... try { Tmp = a/b; }
Aucune exception n'est jamais levée dans ton bloc try.
Ça, on ne peut pas le dire non plus. Il a une division par 0 ; c'est un comportement indéfini, et donc, on ne sait pas ce qui va se passer.
Sur des processeurs qui implémente les flottants IEEE, la division par 0 a un comportement défini, qui est de renvoyer la valeur infini (et non de lever une exception). Sur les autres processeurs que j'ai eu l'occasion d'essayer (et dans le cas de l'arithmetique des entiers sur tous les processeurs), la division par 0 provoque l'arrêt du programme : en fait, il lève un « signal » (non une exception) dont le traitement par défaut est de générer un core dump et de terminer le programme.
Une exception est levée par l'instruction throw et par celle-ci uniquement.
Dans le cas d'un comportement indéfini, tout est possible. Y compris une exception.
double Division(double a, double b) { if(b != 0.0) // éventuellement à affiner car ce sont des doubl es? return a/b;
return -1.0; }
Après, je ne trouve pas cela particulièrement pertinent de définir x/0 comme étant -1...
C'était sans doute à titre d'exemple, et que les conditions d'erreur sont plus complexe dans son code réel.
-- James Kanze (GABI Software) email: Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34