OVH Cloud OVH Cloud

Exception multiples

114 réponses
Avatar
bernard tatin
J'ai un problème d'exceptions multiples qui, je pense, est bien décrit
par le code suivant :

// une exception
class Excp {
public:
Excp(char *msg) : message (msg) {}
virtual ~Excp() {}
inline string& getMessage () {
return message;
}
protected:
string message;
};

// 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;
};

void test_excp () {
try {
try {
B b(-5);
b.run();
std::cout << "Création de B ... et sortie" << std::endl;
}
catch (Excp &e) {
std::cout << "Exception " << e.getMessage() << std::endl;
}
}
catch (Excp &e) {
std::cout << "Exception " << e.getMessage() << std::endl;
}
catch (...) {
std::cout << "Exception inconnue" << std::endl;
}
}

int main () {
test_excp ();
return 0;
}

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.

Merci.

Bernard.

10 réponses

8 9 10 11 12
Avatar
James Kanze
"Michel Michaud" writes:

|> Dans le message ,
|> > Jean-Marc Bourguet writes:
|> >> Gabriel Dos Reis writes:
|> >>> Je regrette que le dernier XC++ soit encore aussi anti-export.
|> >>> :-(

|> >> Je ne l'ai pas lu. Mais bon, si on n'utilise pas le bon mécanisme
|> >> d'instantiation, export n'a que des avantages de "propreté" et
|> >> c'est vrai que dans ces conditions on peut douter de son intérêt.

|> > Mais de là à conseiller « avoid export » ?

|> Bah, il y a tout de même des précédents, comme James qui, encore
|> aujourd'hui, conseille généralement « avoid <iostream> » à cause des
|> problèmes de portabilité...

« Encore aujourd'hui » va un peu loin:-). Aujourd'hui, je dirais que
c'est un aspect qu'il faut encore considérer, mais selon le cas... En
fait, si tu sais que si tu dois porter sur g++, ça serait une version
plus récente de 3.0, tu peux tranquillement te servir de <iostream> --
même plus, tu dois te servir de <iostream>, parce que g++ (comme
malheureusement certains autres) ne supporte plus <iostream.h>.

Mais c'est vrai que l'évolution dans ma position a été récente, et
qu'elle est en conséquence du fait que les versions post-3.0 de g++ ont
atteintes une certaine stabilité, et que les versions plus récentes sont
tout à fait utilisable. Il n'y a, à mon avis, plus aucune raison à
rester avec g++ 2.95.2, sauf si tu as du code existant (parce que g++
n'offre pas de solution de continuité ou de compatibilité ancienne ici).

|> Pour bien des gens, la question ne se pose pas : le verbe « avoid »
|> est mal choisi quand c'est quelque chose qu'on ne peut même pas
|> utiliser, mais le résultat est le même : Herb peut prétendre que
|> tout le monde (ou presque) suit son conseil ou pense comme lui :-)

|> (Il me semble que ce serait facile d'avoir tous les compilateurs
|> pressés d'implémenter export, il suffirait que gcc le supporte...)

Tout à fait. Du moment que g++ le fait, je crois que tous les
compilateurs commerciaux seront obligés à s'aligner.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
James Kanze
"Michel Michaud" writes:

|> Dans le message ,
|> > Jean-Marc Bourguet wrote in message
|> > news:...
|> >> Je viens de verifier, le code que nous livrons n'est pas compile
|> >> avec -DNDEBUG et il me semblait que c'etait une pratique courante.

|> > Ça a été la pratique courante partout où j'ai travaillé, en tout
|> > cas.

|> Il me semble qu'il faut alors en avertir les programmeurs qui
|> auraient bien pu mettre des assert pour eux, qui demandent beaucoup
|> de temps de calcul, etc., en pensant qu'ils seraient désactivés
|> avant la livraison. En fait, il me semble même que c'est à quoi
|> devrait servir assert :-) sinon pourquoi toute cette histoire de
|> NDEBUG ?

Je croyais bien l'avoir expliquer. L'intérêt de NDBUG, c'est de pouvoir
supprimer les asserts dans une (seule) function où le profiler a montré
que c'est nécessaire. C'est lié au fait qu'on peut inclure <assert.h> de
multiples fois, et que chaque fois, il rédéfinit le macro selon la
valeur de NDEBUG. Donc, autour d'une fonction où le profiler a montré un
problème :

#define NDEBUG
#include <assert.h>

// fonction critique

#undef NDEBUG
#include <assert.h>

C'est au moins comme ça que je l'ai compris, et c'est ce que j'ai
réelement vu dans la pratique.

|> Si on veut laisser des tests dans un programme livré, il me semble
|> que c'est un détournement que d'utiliser assert. D'autres genres de
|> test, avec surtout un meilleur mécanisme de rapport d'erreurs, sera
|> une une meilleur idée.

En fait, il n'est pas rare de remplacer <assert.h>. Formellement, c'est
un comportement indéfini, mais pratiquement, ça marche.

Plus généralement, aussi, ça dépend de l'application. J'ai travaillé sur
beaucoup d'applications où l'assert standard était tout à fait
acceptable.

|> D'ailleurs tu indiques dans d'autres messages que tu utilises un
|> assert modifié ou différent de celui normalement fourni... Si ce
|> n'est pas (std::)assert, ne pas l'appeler assert !

Il n'y a pas de std::assert. La norme exige que assert soit un macro, de
façon à ce qu'on puisse le rédéfinir dans l'unité de compilation.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
Gabriel Dos Reis
James Kanze writes:

[...]

| Je suis donc obligé à dire qu'on ne doit pas utiliser export.

Normalement, tu es censé avoir reçu un exemplaire du bouquin.

-- Gaby
Avatar
James Kanze
Gabriel Dos Reis writes:

|> James Kanze writes:

|> [...]

|> | Je suis donc obligé à dire qu'on ne doit pas utiliser export.

|> Normalement, tu es censé avoir reçu un exemplaire du bouquin.

Normalement, il l'a envoyé par voie postale. Alors, je suis censé
recevoir un exemplaire, on ne sait pas trop quand:-).

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
Laurent Deniau
Daveed Vandevoorde wrote:
Fabien LE LEZ wrote in message news:...

On 29 Oct 2004 08:24:57 -0700, (Daveed
Vandevoorde):


Neanmoins, le modele de
separation est quand-meme tres agreable pour ce genre de
projet la aussi.


Qu'apporte-t-il exactement ?

Je veux dire, quels sont les avantages réels de "export" en-dehors
d'un problème de temps de compilation ?



La separation protege contre l'interference d'autres declarations
(les macros en particuliers).

Pour certains, la possibilite de distribuer des definition templates
en forme binaire est attrayant aussi.


Il y a une ABI commune/standardise qui est suivie ou propose?

a+, ld.



Avatar
google
Jean-Marc Bourguet wrote:
(Daveed Vandevoorde) writes:

Pour clarification: Nous etions 3 personnes (Comeau ne
fait que recompiler nos sources; je le compte pas dans
l'effort d'implementation, bien que jusqu'a recemment
c'etait grace a lui que l'implementation etait
accessible).


Ne sachant pas exactement ce que vous fournissiez à vos
clients, je ne voulais pas ignorer la possibilité qu'ils
aient besoin d'un travail significatif (?) pour fournir une
implémentation utilisable -- en particulier puisqu'Intel ne
l'a pas fourni directement.


Apres reflection, je me realise qu'en fait tu avais raison:
Il y avait une 4me personne (et une 2me petite societe).
Glen McCluskey a ecrit la plupart de nos tests pour
export (des milliers, literalement). Sans lui, la qualite
de l'implementation aurait ete moins bonne.

L'implementation a pris 1 1/2 ans et pendant cette meme
periode nous avons ajoute un mode de compatibilite gcc
(e.g., permettant de compiler le kernel Linux): Pas un
petit projet non plus.


Non, surtout qu'il devait là dedans avoir des choses encore
moins bien définie qu'export je suppose :-)


J'etait surpris en fait qu'export n'avait pas tellement de
problemes de definition, en considerant la magnitude de
nouveaute. Il y avait quelques surprises (comme un aspect
d'accessibilite auquel allude Herb dans ses articles), mais
en tout il y avait vraiment peu de probleme du type "le
standard ne dit pas ce qu'on doit faire dans ce cas". Par
example, l'addition d'arguments explicite sur les function
templates (quand-meme beaucoup plus modeste comme
extension) avait cree bien plus de problemes de ce type.

Quand a l'emulation de gcc et g++: Oui, c'est un tout autre
type de travaille. Souvent, l'implementation est assez facile,
mais la recherche necessaire pour decider ce que le compilo
fait prends du temps. Ca me plait comme boulot, d'habitude.
Parfois la recherche me permet de deviner un choix
d'implementation soujacent et ensuite ca me pointe vers de
nouveaux bogues de la meme famille. (Et meme chose pour
les emulations Microsoft et Sun.)

David


Avatar
google
drkm wrote in message news:...
(Daveed Vandevoorde) writes:

[critique intéressante]

- Il pretend que les "dependences" sont les memes pour export
que pour les templates inclues. C'est incorrecte.


De quelles dépendences parles-tu ? Peux-tu donner l'une ou l'autre
différence, ou une URL ou une référence dans la norme énonçant ces
différences ?


Les dependences entre le client (le point d'instantation) et l'implementation
(le template): Si l'un change, dans quel mesure l'autre est affecte?

Si le client change, le modele d'inclusion recompile toujours tout les
template inclus. Il y des trucs (comme les entetes precompiles) pour
addoucir le cout, mais ils ne marchent pas toujours. Avec export, ca
n'est pas necessaire parce qu'une version compile du template peut
etre accessible. En fait, dans bien des cas il n'est meme pas necessaire
de re-instantier le template (parce que le point d'instantiation etait
inactif).

Si le template change, le modele d'inclusion voit tous les "translation
units" qui inclue ce template affecte. Eviter les recompilations superflue
est nettement plus difficile dans ce cas (probablement plus complexe que
l'implementation d'export). Avec export, seulement le "translation unit"
contenant la template doit etre recompile et les instantiations base sur
cette template doivent etre recree (mais ca peut ce faire a partir d'une
ou plusieurs "translation unit" deja compile).

Note que je parle ici de "non-inline function templates" et de "static
data members of class templates". Ce sont les seuls templates vraiment
exporte.

Pour ceux que ca interesse, j'ai recemment propose informellement
un systeme de modules pour C++ qui permetrai d'etendre ce principe
a d'autres entitees C++ (pas just les template export). La proposition
est en partie le produit de mon experience avec l'implementation
d'export. J'espere soumettre une premiere version formelle (lire: ecrite)
de cette proposition d'ici lundi. On verra si c'est realisable.

David


Avatar
google
Laurent Deniau wrote:
Daveed Vandevoorde wrote:
Fabien LE LEZ wrote:

On 29 Oct 2004 08:24:57 -0700, (Daveed
Vandevoorde):


Neanmoins, le modele de
separation est quand-meme tres agreable pour ce genre de
projet la aussi.


Qu'apporte-t-il exactement ?

Je veux dire, quels sont les avantages réels de "export" en-dehors
d'un problème de temps de compilation ?



La separation protege contre l'interference d'autres declarations
(les macros en particuliers).

Pour certains, la possibilite de distribuer des definition templates
en forme binaire est attrayant aussi.


Il y a une ABI commune/standardise qui est suivie ou propose?


Non et c'est une bonne question. (ABI n'est peut-etre pas le concepte
exacte, mais je pense comprendre la question.)

Ce probleme la devient plus aigu dans une proposition pour un systeme
de modules pour C++ sur lequel je travaille en ce moment. Un des
seuls avantages de l'inclusion par preprocesseur et qu'il n'y pas un
"language d'interface separe et nonstandard". Pour un distributeur
de libraries il est souvent acceptable de produire des version specifique
pour chaque compilateur. Mais pour un produit d'analyse de programme
par exemple (disons "lint"), remplace des en-tetes C++ par des fichiers
binaires opaques est un probleme epineux.

David




Avatar
Jean-Marc Bourguet
(Daveed Vandevoorde) writes:

Le dernier compilo Intel implemente "export."


Je viens de le récupérer pour Linux (licence "non
commerciale"), de faire quelques tests et de reporter mon
premier problème (qui n'est pas présent chez como par
ailleurs).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
drkm
(Daveed Vandevoorde) writes:

Si le template change, le modele d'inclusion voit tous les "translation
units" qui inclue ce template affecte. Eviter les recompilations superflue
est nettement plus difficile dans ce cas (probablement plus complexe que
l'implementation d'export). Avec export, seulement le "translation unit"
contenant la template doit etre recompile et les instantiations base sur
cette template doivent etre recree (mais ca peut ce faire a partir d'une
ou plusieurs "translation unit" deja compile).


Donc si je comprends bien, si un template exporté change, on n'a pas
besoin des sources des TUs qui l'utilisent, juste des fichiers objet
de ces TUs ?

Si c'est le cas, il est clair que les relations de dépendances sont
extrêmement différentes.

Pour ceux que ca interesse, j'ai recemment propose informellement
un systeme de modules pour C++


Grande nouvelle. Je trouve que c'est une lacune importante de C++.

--drkm

8 9 10 11 12