// une classe simple
class B {
public:
B(int j) : k(j) {}
inline void run () {
throw Excp("exception imprévue dans le run");
}
virtual ~B () { throw Excp("Bad B"); }
private:
int k;
};
Je comprend que l'exception déclenchée dans b.run() provoque la sortie
du bloc et donc la destruction de l'objet b. Une nouvelle exception est
alors levée. Je pensais que mes try/catch résolverais le problème, mais
ce n'est pas le cas. J'ai un message
Executable tests has exited due to signal 6 (SIGABRT).
Et rien d'autre. C'est un vrai plantage. Si je supprime l'un des deux
throw, j'ai le résultat attendu.
J'utilise gcc 3.3 sur MacOS 10.3.5.
Est-ce que quelqu'un a des explications ? Je sais comment m'en dépétrer,
ce qui m'intéresse c'est le pourquoi du comment.
On Tue, 26 Oct 2004 23:12:17 +0200, bernard tatin :
Excp(char *msg)
char const* msg
virtual ~B () { throw Excp("Bad B"); }
Un destructeur ne doit pas lancer d'exception.
Je comprend que l'exception déclenchée dans b.run() provoque la sortie du bloc et donc la destruction de l'objet b. Une nouvelle exception est alors levée.
... et comme C++ ne sait pas gérer ça, le programme s'arrête.
En gros, garde à l'esprit qu'on ne lance jamais d'exception dans un destructeur, et tout ira bien.
-- ;-)
On Tue, 26 Oct 2004 23:12:17 +0200, bernard tatin
<bernard.tatin@nospam.tele2.fr>:
Excp(char *msg)
char const* msg
virtual ~B () { throw Excp("Bad B"); }
Un destructeur ne doit pas lancer d'exception.
Je comprend que l'exception déclenchée dans b.run() provoque la sortie
du bloc et donc la destruction de l'objet b. Une nouvelle exception est
alors levée.
... et comme C++ ne sait pas gérer ça, le programme s'arrête.
En gros, garde à l'esprit qu'on ne lance jamais d'exception dans un
destructeur, et tout ira bien.
On Tue, 26 Oct 2004 23:12:17 +0200, bernard tatin :
Excp(char *msg)
char const* msg
virtual ~B () { throw Excp("Bad B"); }
Un destructeur ne doit pas lancer d'exception.
Je comprend que l'exception déclenchée dans b.run() provoque la sortie du bloc et donc la destruction de l'objet b. Une nouvelle exception est alors levée.
... et comme C++ ne sait pas gérer ça, le programme s'arrête.
En gros, garde à l'esprit qu'on ne lance jamais d'exception dans un destructeur, et tout ira bien.
-- ;-)
drkm
bernard tatin writes:
virtual ~B () { throw Excp("Bad B"); }
Une exception dans un destructeur, ça me paraît suspect. Qu'en pensez vous ?
Il me semble que dans ton exemple, une exception est levée alors qu'une première l'a déjà été :
1/ run() lève une exception ;
2/ b est donc détruit, avant de rentrer dans le gestionnaire de l'exception ;
3/ le destructeur lève lui-même une exception. Boom.
Je ne sais pas ce que dit la norme à ce propos. Mais il me semble qu'aborter et plutôt sage.
--drkm
bernard tatin <bernard.tatin@nospam.tele2.fr> writes:
virtual ~B () { throw Excp("Bad B"); }
Une exception dans un destructeur, ça me paraît suspect. Qu'en
pensez vous ?
Il me semble que dans ton exemple, une exception est levée alors
qu'une première l'a déjà été :
1/ run() lève une exception ;
2/ b est donc détruit, avant de rentrer dans le gestionnaire de
l'exception ;
3/ le destructeur lève lui-même une exception. Boom.
Je ne sais pas ce que dit la norme à ce propos. Mais il me semble
qu'aborter et plutôt sage.
3/ le destructeur lève lui-même une exception. Boom.
Je ne sais pas ce que dit la norme à ce propos.
Apparemment, la fonction terminate() est appelée <http://www.gotw.ca/gotw/047.htm>.
-- ;-)
drkm
drkm writes:
Je ne sais pas ce que dit la norme à ce propos. Mais il me semble qu'aborter et plutôt sage.
15.2/3 :
The process of calling destructors for automatic objects constructed on the path from a try block to a /throw-expression/ is called "/stack unwinding/". [Note: If a destructor called during stack unwinding exists with an exception, _terminate_ is called (15.5.1). So destructors should generally catch exceptions and not let them propagate out of the destructor.]
--drkm
drkm <usenet.fclcxx@fgeorges.org> writes:
Je ne sais pas ce que dit la norme à ce propos. Mais il me semble
qu'aborter et plutôt sage.
15.2/3 :
The process of calling destructors for automatic objects
constructed on the path from a try block to a /throw-expression/
is called "/stack unwinding/". [Note: If a destructor called
during stack unwinding exists with an exception, _terminate_ is
called (15.5.1). So destructors should generally catch exceptions
and not let them propagate out of the destructor.]
Je ne sais pas ce que dit la norme à ce propos. Mais il me semble qu'aborter et plutôt sage.
15.2/3 :
The process of calling destructors for automatic objects constructed on the path from a try block to a /throw-expression/ is called "/stack unwinding/". [Note: If a destructor called during stack unwinding exists with an exception, _terminate_ is called (15.5.1). So destructors should generally catch exceptions and not let them propagate out of the destructor.]
--drkm
drkm
Fabien LE LEZ writes:
On Tue, 26 Oct 2004 23:12:17 +0200, bernard tatin :
virtual ~B () { throw Excp("Bad B"); }
Un destructeur ne doit pas lancer d'exception.
Ca me semble en effet une bonne règle générale. Mais ce n'est pas formellement interdit. Cfr. mon autre article.
--drkm
Fabien LE LEZ <gramster@gramster.com> writes:
On Tue, 26 Oct 2004 23:12:17 +0200, bernard tatin
<bernard.tatin@nospam.tele2.fr>:
virtual ~B () { throw Excp("Bad B"); }
Un destructeur ne doit pas lancer d'exception.
Ca me semble en effet une bonne règle générale. Mais ce n'est pas
formellement interdit. Cfr. mon autre article.
Je pressentais bien qu'une excception dans un destructeur n'était pas une bonne idée,
pas forcement.
mais je ne trouvais rien à ce sujet.
voir uncaught_exception().
a+, ld.
Fabien LE LEZ
On Wed, 27 Oct 2004 00:05:34 +0200, drkm :
Un destructeur ne doit pas lancer d'exception.
Ca me semble en effet une bonne règle générale. Mais ce n'est pas formellement interdit.
Disons qu'un destructeur peut effectivement lancer une exception en cas de crise grave (i.e. le programme ne peut vraiment pas continuer), mais dans ce cas, autant appeler abort() carrément.
-- ;-)
On Wed, 27 Oct 2004 00:05:34 +0200, drkm <usenet.fclcxx@fgeorges.org>:
Un destructeur ne doit pas lancer d'exception.
Ca me semble en effet une bonne règle générale. Mais ce n'est pas
formellement interdit.
Disons qu'un destructeur peut effectivement lancer une exception en
cas de crise grave (i.e. le programme ne peut vraiment pas continuer),
mais dans ce cas, autant appeler abort() carrément.
Ca me semble en effet une bonne règle générale. Mais ce n'est pas formellement interdit.
Disons qu'un destructeur peut effectivement lancer une exception en cas de crise grave (i.e. le programme ne peut vraiment pas continuer), mais dans ce cas, autant appeler abort() carrément.
-- ;-)
bernard tatin
Fabien LE LEZ wrote:
Disons qu'un destructeur peut effectivement lancer une exception en cas de crise grave (i.e. le programme ne peut vraiment pas continuer), mais dans ce cas, autant appeler abort() carrément.
Dans mon programme, pas dans mon exemple, c'est vraiment le cas. Lorsque le programme qui utilise ma classe est bien écrit, bien testé et la classe utilisée correctement, l'exception ne devrait jamais être levée.
J'espérais que cette exception soit récupérable et que toutes les resources allouées soient désallouées proprement. Abort et exit sont un peu plus brutales.
Finalement, j'ai remplacé l'exception par un exit() avec un code qui me va bien.
Merci. Bernard.
Fabien LE LEZ wrote:
Disons qu'un destructeur peut effectivement lancer une exception en
cas de crise grave (i.e. le programme ne peut vraiment pas continuer),
mais dans ce cas, autant appeler abort() carrément.
Dans mon programme, pas dans mon exemple, c'est vraiment le cas. Lorsque
le programme qui utilise ma classe est bien écrit, bien testé et la
classe utilisée correctement, l'exception ne devrait jamais être levée.
J'espérais que cette exception soit récupérable et que toutes les
resources allouées soient désallouées proprement. Abort et exit sont un
peu plus brutales.
Finalement, j'ai remplacé l'exception par un exit() avec un code qui me
va bien.
Disons qu'un destructeur peut effectivement lancer une exception en cas de crise grave (i.e. le programme ne peut vraiment pas continuer), mais dans ce cas, autant appeler abort() carrément.
Dans mon programme, pas dans mon exemple, c'est vraiment le cas. Lorsque le programme qui utilise ma classe est bien écrit, bien testé et la classe utilisée correctement, l'exception ne devrait jamais être levée.
J'espérais que cette exception soit récupérable et que toutes les resources allouées soient désallouées proprement. Abort et exit sont un peu plus brutales.
Finalement, j'ai remplacé l'exception par un exit() avec un code qui me va bien.
Merci. Bernard.
Laurent Deniau
bernard tatin wrote:
Fabien LE LEZ wrote:
Disons qu'un destructeur peut effectivement lancer une exception en cas de crise grave (i.e. le programme ne peut vraiment pas continuer), mais dans ce cas, autant appeler abort() carrément.
Dans mon programme, pas dans mon exemple, c'est vraiment le cas. Lorsque le programme qui utilise ma classe est bien écrit, bien testé et la classe utilisée correctement, l'exception ne devrait jamais être levée.
J'espérais que cette exception soit récupérable et que toutes les resources allouées soient désallouées proprement.
Cela reste possible. Pourquoi ne pas le faire?
Abort et exit sont un peu plus brutales.
abort() et exit() te permettent d'intervenir avant de quitter definitivement.
Finalement, j'ai remplacé l'exception par un exit() avec un code qui me va bien.
plus c'est simple mieux c'est, du moment que ca te convient.
a+, ld.
bernard tatin wrote:
Fabien LE LEZ wrote:
Disons qu'un destructeur peut effectivement lancer une exception en
cas de crise grave (i.e. le programme ne peut vraiment pas continuer),
mais dans ce cas, autant appeler abort() carrément.
Dans mon programme, pas dans mon exemple, c'est vraiment le cas. Lorsque
le programme qui utilise ma classe est bien écrit, bien testé et la
classe utilisée correctement, l'exception ne devrait jamais être levée.
J'espérais que cette exception soit récupérable et que toutes les
resources allouées soient désallouées proprement.
Cela reste possible. Pourquoi ne pas le faire?
Abort et exit sont un
peu plus brutales.
abort() et exit() te permettent d'intervenir avant de quitter
definitivement.
Finalement, j'ai remplacé l'exception par un exit() avec un code qui me
va bien.
plus c'est simple mieux c'est, du moment que ca te convient.
Disons qu'un destructeur peut effectivement lancer une exception en cas de crise grave (i.e. le programme ne peut vraiment pas continuer), mais dans ce cas, autant appeler abort() carrément.
Dans mon programme, pas dans mon exemple, c'est vraiment le cas. Lorsque le programme qui utilise ma classe est bien écrit, bien testé et la classe utilisée correctement, l'exception ne devrait jamais être levée.
J'espérais que cette exception soit récupérable et que toutes les resources allouées soient désallouées proprement.
Cela reste possible. Pourquoi ne pas le faire?
Abort et exit sont un peu plus brutales.
abort() et exit() te permettent d'intervenir avant de quitter definitivement.
Finalement, j'ai remplacé l'exception par un exit() avec un code qui me va bien.
plus c'est simple mieux c'est, du moment que ca te convient.