Si je simplifie :
- dans un fichier module1.hpp j'ai une méthode qui lance une exception
void f()
{
throw CException("blabla");
}
- dans un fichier module2.cpp, j'ai une méthode qui appelle f
void g()
{
f();
}
- dans un fichier module3.cpp, j'ai une méthode qui appelle g
void h()
{
try {
g();
}
catch(CException &e)
{
output << e.what();
}
}
par le jeu des inclusions, la méthode h connait g qui connait f => pas de pb
à la compilation
mais à l'exécution, ça plante. En fait e.what() affiche n'importe quoi et le
programme devient instable.
Pour que ça marche, il faut que j'écrive g comme suit :
void g()
{
try {
f();
}
catch(CException &) { throw; }
}
c'est-à-dire qu'il faut que j'intercepte l'exception pour la relancer.
Je comprends pas bien pourquoi.
C'est la norme ou mon compilo qui merdouille ?
Merci à vous.
par le jeu des inclusions, la méthode h connait g qui connait f => pas de pb à la compilation mais à l'exécution, ça plante. En fait e.what() affiche n'importe quoi et le programme devient instable. Pour que ça marche, il faut que j'écrive g comme suit : void g() { try { f(); } catch(CException &) { throw; } } c'est-à-dire qu'il faut que j'intercepte l'exception pour la relancer. Je comprends pas bien pourquoi. C'est la norme ou mon compilo qui merdouille ?
A vue de nez il s'agit de ton compilo...
Wild guess... tu utilises VC6? (le nommage CException me fait penser à MS, et il n'y a que le 6 qui puisse être aussi buggé :-p)
par le jeu des inclusions, la méthode h connait g qui connait f =>
pas de pb à la compilation
mais à l'exécution, ça plante. En fait e.what() affiche n'importe
quoi et le programme devient instable.
Pour que ça marche, il faut que j'écrive g comme suit :
void g()
{
try {
f();
}
catch(CException &) { throw; }
}
c'est-à-dire qu'il faut que j'intercepte l'exception pour la
relancer. Je comprends pas bien pourquoi.
C'est la norme ou mon compilo qui merdouille ?
A vue de nez il s'agit de ton compilo...
Wild guess... tu utilises VC6? (le nommage CException me fait penser
à MS, et il n'y a que le 6 qui puisse être aussi buggé :-p)
par le jeu des inclusions, la méthode h connait g qui connait f => pas de pb à la compilation mais à l'exécution, ça plante. En fait e.what() affiche n'importe quoi et le programme devient instable. Pour que ça marche, il faut que j'écrive g comme suit : void g() { try { f(); } catch(CException &) { throw; } } c'est-à-dire qu'il faut que j'intercepte l'exception pour la relancer. Je comprends pas bien pourquoi. C'est la norme ou mon compilo qui merdouille ?
A vue de nez il s'agit de ton compilo...
Wild guess... tu utilises VC6? (le nommage CException me fait penser à MS, et il n'y a que le 6 qui puisse être aussi buggé :-p)
Cheers, -- IR
Marc G
Wild guess... tu utilises VC6? (le nommage CException me fait penser à MS, et il n'y a que le 6 qui puisse être aussi buggé :-p)
non, j'utilise C++ Builder 6 et CException, c'est une classe personnelle (qui gère des compteurs du nbre d'exceptions levées dans certains cas). C'est la première fois que je remarque ça et ça m'embête. Donc j'aimerais bien que ce soit la norme :-)) ! Mon projet commence à devenir "gros" et "compliqué" et s'il devient bizarroïde, je suis mal parti. Marc
Wild guess... tu utilises VC6? (le nommage CException me fait penser
à MS, et il n'y a que le 6 qui puisse être aussi buggé :-p)
non, j'utilise C++ Builder 6 et CException, c'est une classe personnelle
(qui gère des compteurs du nbre d'exceptions levées dans certains cas).
C'est la première fois que je remarque ça et ça m'embête. Donc j'aimerais
bien que ce soit la norme :-)) !
Mon projet commence à devenir "gros" et "compliqué" et s'il devient
bizarroïde, je suis mal parti.
Marc
Wild guess... tu utilises VC6? (le nommage CException me fait penser à MS, et il n'y a que le 6 qui puisse être aussi buggé :-p)
non, j'utilise C++ Builder 6 et CException, c'est une classe personnelle (qui gère des compteurs du nbre d'exceptions levées dans certains cas). C'est la première fois que je remarque ça et ça m'embête. Donc j'aimerais bien que ce soit la norme :-)) ! Mon projet commence à devenir "gros" et "compliqué" et s'il devient bizarroïde, je suis mal parti. Marc
Sylvain
Marc G wrote on 08/03/2007 21:18:
- dans un fichier module1.hpp j'ai une méthode qui lance une exception void f() { throw CException("blabla"); }
tu veux ici récupérer une référence ... qui a des chances de pointer sur quoi selon toi ? la pile qui contenait g et f a été dépilé lorsque tu entres dans ton handler - remplace simplement par catch(CException e) (s'il s'agit du type des MFC, elles sont correctement copiables).
C'est la norme ou mon compilo qui merdouille ?
on s'oublie souvent dans la liste des sources possibles ...
Sylvain.
Marc G wrote on 08/03/2007 21:18:
- dans un fichier module1.hpp j'ai une méthode qui lance une exception
void f() {
throw CException("blabla");
}
tu veux ici récupérer une référence ... qui a des chances de pointer sur
quoi selon toi ? la pile qui contenait g et f a été dépilé lorsque tu
entres dans ton handler - remplace simplement par catch(CException e)
(s'il s'agit du type des MFC, elles sont correctement copiables).
C'est la norme ou mon compilo qui merdouille ?
on s'oublie souvent dans la liste des sources possibles ...
tu veux ici récupérer une référence ... qui a des chances de pointer sur quoi selon toi ? la pile qui contenait g et f a été dépilé lorsque tu entres dans ton handler - remplace simplement par catch(CException e) (s'il s'agit du type des MFC, elles sont correctement copiables).
C'est la norme ou mon compilo qui merdouille ?
on s'oublie souvent dans la liste des sources possibles ...
Sylvain.
Sylvain
IR wrote on 08/03/2007 22:40:
Wild guess... tu utilises VC6? (le nommage CException me fait penser à MS, et il n'y a que le 6 qui puisse être aussi buggé :-p)
médisance pure ! et d'abord VC5 est largement plus buggé.
Sylvain.
IR wrote on 08/03/2007 22:40:
Wild guess... tu utilises VC6? (le nommage CException me fait penser
à MS, et il n'y a que le 6 qui puisse être aussi buggé :-p)
médisance pure ! et d'abord VC5 est largement plus buggé.
Wild guess... tu utilises VC6? (le nommage CException me fait penser à MS, et il n'y a que le 6 qui puisse être aussi buggé :-p)
médisance pure ! et d'abord VC5 est largement plus buggé.
Sylvain.
Fabien LE LEZ
On Thu, 8 Mar 2007 21:18:57 +0100, "Marc G" :
catch(CException &e)
Pourquoi est-ce une référence au lieu d'être une référence const ? As-tu besoin de modifier e ?
par le jeu des inclusions,
Tu as donc bien la même définition pour CException partout ? (Avec les #define en pagaille des headers Windows, on est en droit de se méfier.)
la méthode h connait g qui connait f => pas de pb à la compilation mais à l'exécution, ça plante. En fait e.what() affiche n'importe quoi et le programme devient instable.
Si tu remplaces CException par un truc très simple, ça donne quoi ?
On Thu, 8 Mar 2007 21:18:57 +0100, "Marc G" <mgueguen@metrica.fr>:
catch(CException &e)
Pourquoi est-ce une référence au lieu d'être une référence const ?
As-tu besoin de modifier e ?
par le jeu des inclusions,
Tu as donc bien la même définition pour CException partout ?
(Avec les #define en pagaille des headers Windows, on est en droit de
se méfier.)
la méthode h connait g qui connait f => pas de pb
à la compilation
mais à l'exécution, ça plante. En fait e.what() affiche n'importe quoi et le
programme devient instable.
Si tu remplaces CException par un truc très simple, ça donne quoi ?
Pourquoi est-ce une référence au lieu d'être une référence const ? As-tu besoin de modifier e ?
par le jeu des inclusions,
Tu as donc bien la même définition pour CException partout ? (Avec les #define en pagaille des headers Windows, on est en droit de se méfier.)
la méthode h connait g qui connait f => pas de pb à la compilation mais à l'exécution, ça plante. En fait e.what() affiche n'importe quoi et le programme devient instable.
Si tu remplaces CException par un truc très simple, ça donne quoi ?
James Kanze
On Mar 8, 11:56 pm, Sylvain wrote:
Marc G wrote on 08/03/2007 21:18:
- dans un fichier module1.hpp j'ai une méthode qui lance une exception void f() { throw CException("blabla"); }
tu lances ici une instance temporaire.
Qui est copié quelque part ? (Où, c'est un sécret de l'implémentation.)
tu veux ici récupérer une référence ... qui a des chances de poin ter sur quoi selon toi ?
S'il ne pointe pas sur la copie, l'implémentation est vraiment bugguée. (En fait, je n'ai jamais entendu parler d'une implémentation qui avait ce problème.)
la pile qui contenait g et f a été dépilé lorsque tu entres dans ton handler - remplace simplement par catch(CException e) (s'il s'agit du type des MFC, elles sont correctement copiables).
C'est pourquoi la norme exige que l'implémentation fait une copie. Elle définit aussi une durée de vie spéciale aux exceptions ; l'objet est construit dans l'expression de throw, et détruit lors qu'on sort du catch (à condition de ne pas avoir fait throw de nouveau dans le catch).
(Aussi, c'est une de ces copies que le compilateur a droit d'optimiser. Il se peut donc que dans l'expression : throw CException("blabla"); on construit directement l'objet qui va servir dans l'exception, sans passer par un temporaire.)
C'est la norme ou mon compilo qui merdouille ?
on s'oublie souvent dans la liste des sources possibles ...
Une cause possible du problème, évidemment, c'est que son constructeur de copie n'est pas tout à fait catholique. Mais je me doute plutôt d'une autre chose : qu'il a compilé g() sans support pour les exceptions. VC++, au moins, ne l'active pas par défaut (au moins, pas dans les anciennes versions---je n'ai pas essayé de compiler avec la nouvelle sans /EHs). Ce qui expliquerait pourquoi en ajoutant le catch/throw dans g(), ça marche -- ça lui oblige d'activer le support des exceptions.
-- 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 Mar 8, 11:56 pm, Sylvain <noS...@mail.net> wrote:
Marc G wrote on 08/03/2007 21:18:
- dans un fichier module1.hpp j'ai une méthode qui lance une exception
void f() {
throw CException("blabla");
}
tu lances ici une instance temporaire.
Qui est copié quelque part ? (Où, c'est un sécret de
l'implémentation.)
tu veux ici récupérer une référence ... qui a des chances de poin ter sur
quoi selon toi ?
S'il ne pointe pas sur la copie, l'implémentation est vraiment
bugguée. (En fait, je n'ai jamais entendu parler d'une
implémentation qui avait ce problème.)
la pile qui contenait g et f a été dépilé lorsque tu
entres dans ton handler - remplace simplement par catch(CException e)
(s'il s'agit du type des MFC, elles sont correctement copiables).
C'est pourquoi la norme exige que l'implémentation fait une
copie. Elle définit aussi une durée de vie spéciale aux
exceptions ; l'objet est construit dans l'expression de throw,
et détruit lors qu'on sort du catch (à condition de ne pas avoir
fait throw de nouveau dans le catch).
(Aussi, c'est une de ces copies que le compilateur a droit
d'optimiser. Il se peut donc que dans l'expression :
throw CException("blabla");
on construit directement l'objet qui va servir dans l'exception,
sans passer par un temporaire.)
C'est la norme ou mon compilo qui merdouille ?
on s'oublie souvent dans la liste des sources possibles ...
Une cause possible du problème, évidemment, c'est que son
constructeur de copie n'est pas tout à fait catholique. Mais je
me doute plutôt d'une autre chose : qu'il a compilé g() sans
support pour les exceptions. VC++, au moins, ne l'active pas par
défaut (au moins, pas dans les anciennes versions---je n'ai pas
essayé de compiler avec la nouvelle sans /EHs). Ce qui
expliquerait pourquoi en ajoutant le catch/throw dans g(), ça
marche -- ça lui oblige d'activer le support des exceptions.
--
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
tu veux ici récupérer une référence ... qui a des chances de poin ter sur quoi selon toi ?
S'il ne pointe pas sur la copie, l'implémentation est vraiment bugguée. (En fait, je n'ai jamais entendu parler d'une implémentation qui avait ce problème.)
la pile qui contenait g et f a été dépilé lorsque tu entres dans ton handler - remplace simplement par catch(CException e) (s'il s'agit du type des MFC, elles sont correctement copiables).
C'est pourquoi la norme exige que l'implémentation fait une copie. Elle définit aussi une durée de vie spéciale aux exceptions ; l'objet est construit dans l'expression de throw, et détruit lors qu'on sort du catch (à condition de ne pas avoir fait throw de nouveau dans le catch).
(Aussi, c'est une de ces copies que le compilateur a droit d'optimiser. Il se peut donc que dans l'expression : throw CException("blabla"); on construit directement l'objet qui va servir dans l'exception, sans passer par un temporaire.)
C'est la norme ou mon compilo qui merdouille ?
on s'oublie souvent dans la liste des sources possibles ...
Une cause possible du problème, évidemment, c'est que son constructeur de copie n'est pas tout à fait catholique. Mais je me doute plutôt d'une autre chose : qu'il a compilé g() sans support pour les exceptions. VC++, au moins, ne l'active pas par défaut (au moins, pas dans les anciennes versions---je n'ai pas essayé de compiler avec la nouvelle sans /EHs). Ce qui expliquerait pourquoi en ajoutant le catch/throw dans g(), ça marche -- ça lui oblige d'activer le support des exceptions.
-- 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
Marc G
je finis par être perdu dans les conseils contradictoires. D'une manière générale, j'essaye de bien faire et quand je lis une recommandation écrite par une personne "renommée", je m'y plie et je modifie ma façon de faire. Donc, dans l'ouvrage Standards de programmation en C++ Herb Sutter et Andrei Alexandrescu Collection C++ dirigée par Bjarne Stroustrup je lis p 174 (j'ai la version française :-))
Lancez par valeur , capturez par référence. ... Sauf si vous transmettez un pointeur intelligent, ... , vous devez absolument capturer par référence.
tel quel. Mon problème reste donc entier. Mais merci pour tes réflexions. Marc
je finis par être perdu dans les conseils contradictoires.
D'une manière générale, j'essaye de bien faire et quand je lis une
recommandation écrite par une personne "renommée", je m'y plie et je modifie
ma façon de faire.
Donc, dans l'ouvrage
Standards de programmation en C++
Herb Sutter et Andrei Alexandrescu
Collection C++ dirigée par Bjarne Stroustrup
je lis p 174 (j'ai la version française :-))
Lancez par valeur , capturez par référence.
...
Sauf si vous transmettez un pointeur intelligent, ... , vous devez
absolument capturer par référence.
tel quel.
Mon problème reste donc entier.
Mais merci pour tes réflexions.
Marc
je finis par être perdu dans les conseils contradictoires. D'une manière générale, j'essaye de bien faire et quand je lis une recommandation écrite par une personne "renommée", je m'y plie et je modifie ma façon de faire. Donc, dans l'ouvrage Standards de programmation en C++ Herb Sutter et Andrei Alexandrescu Collection C++ dirigée par Bjarne Stroustrup je lis p 174 (j'ai la version française :-))
Lancez par valeur , capturez par référence. ... Sauf si vous transmettez un pointeur intelligent, ... , vous devez absolument capturer par référence.
tel quel. Mon problème reste donc entier. Mais merci pour tes réflexions. Marc
Marc G
Pourquoi est-ce une référence au lieu d'être une référence const ? As-tu besoin de modifier e ?
oui, tu as raison, une référence const serait mieux...
par le jeu des inclusions, Tu as donc bien la même définition pour CException partout ?
(Avec les #define en pagaille des headers Windows, on est en droit de se méfier.)
hélas oui, j'ai un fichier CException.h que j'inclus partout en plus, j'ai défini la classe dans un espace de nommage personnel => pas de risque de confusion
la méthode h connait g qui connait f => pas de pb à la compilation mais à l'exécution, ça plante. En fait e.what() affiche n'importe quoi et le programme devient instable.
Si tu remplaces CException par un truc très simple, ça donne quoi ?
tu veux dire quoi par très simple ? CException est une classe très simple. C'est une classe polymorphe avec des méthodes virtuelles mais dans ce cas je lance un objet de la classe de base !
on va dire que l'essentiel, c'est d'avoir une version du programme qui marche.... Merci à toi.
Pourquoi est-ce une référence au lieu d'être une référence const ?
As-tu besoin de modifier e ?
oui, tu as raison, une référence const serait mieux...
par le jeu des inclusions,
Tu as donc bien la même définition pour CException partout ?
(Avec les #define en pagaille des headers Windows, on est en droit de
se méfier.)
hélas oui, j'ai un fichier CException.h que j'inclus partout
en plus, j'ai défini la classe dans un espace de nommage personnel
=> pas de risque de confusion
la méthode h connait g qui connait f => pas de pb
à la compilation
mais à l'exécution, ça plante. En fait e.what() affiche n'importe quoi et
le
programme devient instable.
Si tu remplaces CException par un truc très simple, ça donne quoi ?
tu veux dire quoi par très simple ?
CException est une classe très simple.
C'est une classe polymorphe avec des méthodes virtuelles mais dans ce cas je
lance un objet de la classe de base !
Pourquoi est-ce une référence au lieu d'être une référence const ? As-tu besoin de modifier e ?
oui, tu as raison, une référence const serait mieux...
par le jeu des inclusions, Tu as donc bien la même définition pour CException partout ?
(Avec les #define en pagaille des headers Windows, on est en droit de se méfier.)
hélas oui, j'ai un fichier CException.h que j'inclus partout en plus, j'ai défini la classe dans un espace de nommage personnel => pas de risque de confusion
la méthode h connait g qui connait f => pas de pb à la compilation mais à l'exécution, ça plante. En fait e.what() affiche n'importe quoi et le programme devient instable.
Si tu remplaces CException par un truc très simple, ça donne quoi ?
tu veux dire quoi par très simple ? CException est une classe très simple. C'est une classe polymorphe avec des méthodes virtuelles mais dans ce cas je lance un objet de la classe de base !
on va dire que l'essentiel, c'est d'avoir une version du programme qui marche.... Merci à toi.
Marc G
Une cause possible du problème, évidemment, c'est que son constructeur de copie n'est pas tout à fait catholique. Mais je me doute plutôt d'une autre chose : qu'il a compilé g() sans Support pour les exceptions. VC++, au moins, ne l'active pas par défaut (au moins, pas dans les anciennes versions---je n'ai pas essayé de compiler avec la nouvelle sans /EHs). Ce qui expliquerait pourquoi en ajoutant le catch/throw dans g(), ça marche -- ça lui oblige d'activer le support des exceptions.
Hélas si ! cette option est activée. Et en plus, j'ai largement utilisé les exceptions dans d'autres parties du programme. Avec succès... Marc
Une cause possible du problème, évidemment, c'est que son
constructeur de copie n'est pas tout à fait catholique. Mais je
me doute plutôt d'une autre chose : qu'il a compilé g() sans
Support pour les exceptions. VC++, au moins, ne l'active pas par
défaut (au moins, pas dans les anciennes versions---je n'ai pas
essayé de compiler avec la nouvelle sans /EHs). Ce qui
expliquerait pourquoi en ajoutant le catch/throw dans g(), ça
marche -- ça lui oblige d'activer le support des exceptions.
Hélas si !
cette option est activée.
Et en plus, j'ai largement utilisé les exceptions dans d'autres parties du
programme. Avec succès...
Marc
Une cause possible du problème, évidemment, c'est que son constructeur de copie n'est pas tout à fait catholique. Mais je me doute plutôt d'une autre chose : qu'il a compilé g() sans Support pour les exceptions. VC++, au moins, ne l'active pas par défaut (au moins, pas dans les anciennes versions---je n'ai pas essayé de compiler avec la nouvelle sans /EHs). Ce qui expliquerait pourquoi en ajoutant le catch/throw dans g(), ça marche -- ça lui oblige d'activer le support des exceptions.
Hélas si ! cette option est activée. Et en plus, j'ai largement utilisé les exceptions dans d'autres parties du programme. Avec succès... Marc
Fabien LE LEZ
On Fri, 9 Mar 2007 11:35:35 +0100, "Marc G" :
Lancez par valeur , capturez par référence.
C'est effectivement un bon conseil. Cf message de James.
On Fri, 9 Mar 2007 11:35:35 +0100, "Marc G" <mgueguen@metrica.fr>:
Lancez par valeur , capturez par référence.
C'est effectivement un bon conseil.
Cf message de James.