C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[TORDU] Exception dans un destructeur, oui mais...
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Aurélien REGAT-BARREL
Guest





PostPosted: Fri Jan 14, 2005 10:09 am    Post subject: [TORDU] Exception dans un destructeur, oui mais... Reply with quote



Bonjour à tous,
tout d'abord bonne année.
Je souhaite améliorer la gestion des erreurs et le système de logs de mon
programme. J'ai ragardé un peu log4cpp, pour l'instant c'est trop usine à
gaz pour moi et ça me satisfait pas trop. Mais la syntaxe utilisée m'a
inspiré un nouveau style d'assertion. Le but est d'écrire ceci:

void DoSomething( int A ) // A doit être un chiffre
{
verify( A < 10 ) << "A n'est pas un chiffre : " << A;
// ...
}

Si l'assertion n'est pas vérifiée, alors le message qui suit sert à
construire un message d'erreur (loggé, affiché, ...) et une exception
VerificattionFailed est levée. Sinon tout continue.
Pour cela je me suis dit que verify() pouvait renvoyer une espèce de flux
qui dans son destructeur déclenche une exception (s'il le faut). Voici mon
programme de test qui fonctionne sous VC++ 7.1 et Devcpp (gcc version
3.3.1).

#include #include <sstream>
#include <string>

class VerificationFailed
{
public:
VerificationFailed( bool Throw ) : // si true lève l'exception dans le
destructeur
throw_( Throw ),
msg_( "VerificationFailed : " )
{}

~VerificationFailed()
{
if ( this->throw_ )
{
throw this->msg_;
}
}

template<typename T>
VerificationFailed & operator << ( const T & t )
{
if ( this->throw_ )
{
std::ostringstream oss;
oss << t;
this->msg_ += oss.str();
}
return *this;
}

private:
bool throw_;
std::string msg_;
};

VerificationFailed verify( bool b )
{
return VerificationFailed( !b );
}

int main()
{
try
{
int A = 9;
std::cout << "debut du programmen";
verify( A < 10 ) << "A n'est pas un chiffre : " << A;
std::cout << "suite du programmen";
++A;
verify( A < 10 ) << "A n'est pas un chiffre : " << A;
std::cout << "fin du programmen";
}
catch ( const std::string & err )
{
std::cerr << err << 'n';
}
std::cin.ignore();
}

J'obtiens le résultat suivant:

debut du programme
suite du programme
VerificationFailed : A n'est pas un chiffre : 10

Cela semble donc marcher, bien que lever une exception dans un destructeur
soit une mauvaise pratique (c'est plutôt sur la règle de la durée de vie
d'un objet renvoyé par une fonction que je m'interroge). Serait-ce
l'exception qui confirme la règle ?
Merci à vous.

--
Aurélien REGAT-BARREL


Back to top
drkm
Guest





PostPosted: Fri Jan 14, 2005 12:16 pm    Post subject: Re: [TORDU] Exception dans un destructeur, oui mais... Reply with quote



"Aurélien REGAT-BARREL" <nospam-aregatba (AT) yahoo (DOT) fr.invalid> writes:

Quote:
Pour cela je me suis dit que verify() pouvait renvoyer une espèce de flux
qui dans son destructeur déclenche une exception (s'il le faut).

A priori, je dirais que si l'un des opérateurs << lance une
exception, le destructeur du flux sera appelé, et là, BOOM ! ÀMHA,
lancer une exception dans un destructeur est extrêmement délicat.

Il faut pouvoir assurer qu'aucune exception ne sera lancée entre la
création et la destruction de chacune des instances. Ce qui doit
pourvoir néanmoins être fait dans certains cas particuliers. Dans ce
cas-ci, il faudrait imposer que les surcharges de l'opérateur << pour
ce flux ne lancent pas d'exceptions.

--drkm

Back to top
Olivier Azeau
Guest





PostPosted: Fri Jan 14, 2005 12:17 pm    Post subject: Re: Exception dans un destructeur, oui mais... Reply with quote




Aurélien REGAT-BARREL wrote:
Quote:
void DoSomething( int A ) // A doit être un chiffre
{
verify( A < 10 ) << "A n'est pas un chiffre : " << A;
// ...
}

Si l'assertion n'est pas vérifiée, alors le message qui suit sert
à
construire un message d'erreur (loggé, affiché, ...) et une
exception
VerificattionFailed est levée. Sinon tout continue.

Pourquoi lever une exception au lieu de tout arreter si c'est une
assertion ?

Quote:
Pour cela je me suis dit que verify() pouvait renvoyer une espèce de
flux
qui dans son destructeur déclenche une exception (s'il le faut).
Voici mon
programme de test qui fonctionne sous VC++ 7.1 et Devcpp (gcc version
3.3.1).

#include #include #include
class VerificationFailed
{
public:
VerificationFailed( bool Throw ) : // si true lève l'exception
dans le
destructeur
throw_( Throw ),
msg_( "VerificationFailed : " )
{}

~VerificationFailed()
{
if ( this->throw_ )
{
throw this->msg_;
}
}

template<typename T
VerificationFailed & operator << ( const T & t )
{
if ( this->throw_ )
{
std::ostringstream oss;
oss << t;
this->msg_ += oss.str();
}
return *this;
}

private:
bool throw_;
std::string msg_;
};

VerificationFailed verify( bool b )
{
return VerificationFailed( !b );
}

int main()
{
try
{
int A = 9;
std::cout << "debut du programmen";
verify( A < 10 ) << "A n'est pas un chiffre : " << A;
std::cout << "suite du programmen";
++A;
verify( A < 10 ) << "A n'est pas un chiffre : " << A;
std::cout << "fin du programmen";
}
catch ( const std::string & err )
{
std::cerr << err << 'n';
}
std::cin.ignore();
}

J'obtiens le résultat suivant:

debut du programme
suite du programme
VerificationFailed : A n'est pas un chiffre : 10

Cela semble donc marcher, bien que lever une exception dans un
destructeur
soit une mauvaise pratique (c'est plutôt sur la règle de la durée
de vie
d'un objet renvoyé par une fonction que je m'interroge). Serait-ce
l'exception qui confirme la règle ?

- Si tu utilises ton 'verify' a l'intérieur d'un destructeur, il
faudra prendre garde a rattraper l'exception dans le destructeur pour
ne pas risquer d'avoir une destruction inachevée.

- Si tu inseres dans ton operator<< le résultat d'une fonction qui
leve une exception, tu auras une 2eme levée d'exception non rattrapée
lors de la destruction de la pile, ce qui est justement le truc a
éviter quand on dit de ne pas lever d'exception dans un destructeur.


Back to top
Aurélien REGAT-BARREL
Guest





PostPosted: Fri Jan 14, 2005 1:02 pm    Post subject: Re: [TORDU] Exception dans un destructeur, oui mais... Reply with quote

Quote:
A priori, je dirais que si l'un des opérateurs << lance une
exception, le destructeur du flux sera appelé, et là, BOOM ! ÀMHA,
lancer une exception dans un destructeur est extrêmement délicat.

Oui. Mais à priori l'opérateur << ne sert qu'à créer le message décrivant
l'erreur, il sera utilisé comme dans cet exemple dans le cadre de
ostringstream. Y'a la concaténation de std::string à surveiller aussi. Je
peux faire ça à la bourrin try {} catch(...) {}.

Quote:
Il faut pouvoir assurer qu'aucune exception ne sera lancée entre la
création et la destruction de chacune des instances. Ce qui doit
pourvoir néanmoins être fait dans certains cas particuliers. Dans ce
cas-ci, il faudrait imposer que les surcharges de l'opérateur << pour
ce flux ne lancent pas d'exceptions.

Mon interrogation concerne plutot le moment de la destruction de l'objet
renvoyé par verify(). Est-ce que l'objet renvoyé par une fonction (par
copie) est immédiatement détruit ?
En gros, est-ce que le code suivant :

VerificationFailed verify( bool b )
{
return VerificationFailed( !b );
}

int a = 0;
verify( a == 0 ) << "coucou";
verify( a == 1 ) << "coucou";


est équivalent au niveau de la portée de l'objet retourné à:

int a = 0;
{
VarificationFailed v1 = verify( a == 0 );
v1 << "coucou";
}// destruction v1
{
VarificationFailed v2 = verify( a == 1 );
v2 << "coucou";
}// destruction v2

ou y a-t-il un risque qu'un compilateur réalise ceci :

{
int a = 0;
VarificationFailed v1 = verify( a == 0 );
v1 << "coucou";
VarificationFailed v2 = verify( a == 1 );
v2 << "coucou";
}// destruction v1 et v2

Dans ce cas je serais bien embêté.


--
Aurélien REGAT-BARREL



Back to top
Aurélien REGAT-BARREL
Guest





PostPosted: Fri Jan 14, 2005 1:17 pm    Post subject: Re: Exception dans un destructeur, oui mais... Reply with quote

Quote:
Pourquoi lever une exception au lieu de tout arreter si c'est une
assertion ?

Ben l'exception est un bon moyen de tout arrêter proprement non ?
Je compte l'utiliser comme un assert() amélioré certes, mais pas seulement,
aussi voire surtout pour vérifier le code de retour de fonctions systèmes /
d'une bibliothèque tierce (pilotage d'une caméra scientifique...). Si une
telle fonction échoue, je peux pas faire grand chose, mais pas la peine de
vautrer tout le logiciel. Cette exception sera catchée un peu plus haut et
transformée en OperationFailed, l'utilisateur averti et puis c'est tout. Le
log contiendra plus de détails sur l'origine de l'échec (le message associé
au verify()).

Quote:
- Si tu utilises ton 'verify' a l'intérieur d'un destructeur, il
faudra prendre garde a rattraper l'exception dans le destructeur pour
ne pas risquer d'avoir une destruction inachevée.

Peu de risques que cela se produise, j'ai quasiment aucun destructeur (je me
suis converti au RAII).

Quote:
- Si tu inseres dans ton operator<< le résultat d'une fonction qui
leve une exception, tu auras une 2eme levée d'exception non rattrapée
lors de la destruction de la pile, ce qui est justement le truc a
éviter quand on dit de ne pas lever d'exception dans un destructeur.

C'est effectivement une possibilité, genre:

verify( value != 0 ) << "La valeur de la classe " << this->getName() << "
est nulle.";

si getName() lève une exception je suis mal...
Peu de risques malgré tout, bad_alloc me semble le principal. Moyennant une
bonne doc écrite en rouge clignotant, on devrait pouvoir s'assurer de la
chose.

Au niveau utilisation, vous en pensez quoi ? Je trouve ça bien plus pratique
que ce que j'ai fait jusque là:

if ( value >= 10 )
{
std::ostringstream oss;
oss << "La valeur n'est pas un chiffre : " << value;
throw std::logic_error( oss.str() );
}

Vous faîtes comment vous ?

--
Aurélien REGAT-BARREL



Back to top
Alexandre
Guest





PostPosted: Fri Jan 14, 2005 6:12 pm    Post subject: Re: [TORDU] Exception dans un destructeur, oui mais... Reply with quote

Quote:
ou y a-t-il un risque qu'un compilateur réalise ceci :

{
int a = 0;
VarificationFailed v1 = verify( a == 0 );
v1 << "coucou";
VarificationFailed v2 = verify( a == 1 );
v2 << "coucou";
}// destruction v1 et v2

Dans ce cas je serais bien embêté.

AMA c'est le cas... je ne sais pas exactement ce que dit la norme, mais il
me semble que tant que v1 est dans la portée (même s'il n'est plus utilisé)
il n'est pas détruit... donc v1 et v2 doivent être détruits lors de la
sortie de la portée...

Quote:


--
Aurélien REGAT-BARREL





Back to top
SerGioGio
Guest





PostPosted: Fri Jan 14, 2005 7:10 pm    Post subject: Re: [TORDU] Exception dans un destructeur, oui mais... Reply with quote

"Alexandre" <alex.g (AT) netcourrier (DOT) com> a écrit dans le message de
news:41e80c66$0$19576$636a15ce (AT) news (DOT) free.fr...
Quote:
ou y a-t-il un risque qu'un compilateur réalise ceci :

{
int a = 0;
VarificationFailed v1 = verify( a == 0 );
v1 << "coucou";
VarificationFailed v2 = verify( a == 1 );
v2 << "coucou";
}// destruction v1 et v2

Dans ce cas je serais bien embêté.

AMA c'est le cas... je ne sais pas exactement ce que dit la norme, mais il
me semble que tant que v1 est dans la portée (même s'il n'est plus
utilisé)
il n'est pas détruit... donc v1 et v2 doivent être détruits lors de la
sortie de la portée...


Pour ma part je ne crois pas. Je pense que la methode d Alexandre
fonctionne. Voir l' article de Bjarne Stroustrup
http://www.research.att.com/~bs/wrapper.pdf ou il utilise la meme technique
pour faire des fonctions prefixes et suffixes.

Pour ce qui est des exceptions dans le destructeur je m'y connais pas
assez... mais une chose est sure la syntaxe de "verify" est interessante!

SerGioGioGio



Back to top
Loïc Joly
Guest





PostPosted: Fri Jan 14, 2005 8:01 pm    Post subject: Re: [TORDU] Exception dans un destructeur, oui mais... Reply with quote

Aurélien REGAT-BARREL wrote:
Quote:
Bonjour à tous,
tout d'abord bonne année.
Je souhaite améliorer la gestion des erreurs et le système de logs de mon
programme. J'ai ragardé un peu log4cpp, pour l'instant c'est trop usine à
gaz pour moi et ça me satisfait pas trop.

Pareil pour moi. J'ai aussi regardé la bibliothèque de log qui se trouve
dans la zone de fichiers de la mailing list boost. Je l'ai trouvée
plutôt sympa, même si je n'ai pas encore eu l'occasion d'essayer.

--
Loïc

Back to top
Loïc Joly
Guest





PostPosted: Fri Jan 14, 2005 8:37 pm    Post subject: Re: Exception dans un destructeur, oui mais... Reply with quote

Aurélien REGAT-BARREL wrote:

Quote:
Pourquoi lever une exception au lieu de tout arreter si c'est une
assertion ?


Ben l'exception est un bon moyen de tout arrêter proprement non ?

Ca se discute. Certains disent qu'en cas d'assert, tu n'es pas certain
de l'état dans lequel tu es, et donc il vaut mieux arrêter tout au plus
vite.

D'autres disent que même si le premier argument est vrai, si le
désagrément causé par un arrêt brutal est relativement élevé, et si ce
qui peut se passer au cas ou le programme perdre totalement les pédales
n'est pas dramatique, vu que la probalité que ça se passe vraiment mal
est assez faible (estimation sans justification...), il vaut mieux
lancer une exception qui va arrêter calmement le programme.

J'avoue ne pas savoir me situer entre les deux camps.



Quote:
Vous faîtes comment vous ?

Je ne fais pas, mais je me demande si un truc tordu comme le suivant
pourrait marcher :

class DoOnceAndThrow
{
DoOnceAndThrow() isAlreadyDone(false) {}
void tryToDoIt()
{
if (isAlreadyDone)
throw std::exception;
isAlreadyDone = true;
}
bool isAlreadyDone;
}

#define verify(b)
DoOnceAndThrow doat##__LINE__; // 1
if (b) ; // 2
else
while(doOnceAndThrow())
log

// 1 : Pour essayer de ne pas avoir deux identificateurs portant le même
nom dans la même portée. Ne marchera que s'il n'y a pas 2 verifie sur
une seule ligne

// 2 : Permet d'éviter des trucs étranges si verifie est appelé dans un
if qui comporte un else, par exemple.

--
Loïc



Back to top
Olivier Azeau
Guest





PostPosted: Fri Jan 14, 2005 11:42 pm    Post subject: Re: Exception dans un destructeur, oui mais... Reply with quote

Aurélien REGAT-BARREL wrote:
Quote:
Pourquoi lever une exception au lieu de tout arreter si c'est une
assertion ?


Ben l'exception est un bon moyen de tout arrêter proprement non ?
Je compte l'utiliser comme un assert() amélioré certes, mais pas seulement,
aussi voire surtout pour vérifier le code de retour de fonctions systèmes /
d'une bibliothèque tierce (pilotage d'une caméra scientifique...). Si une
telle fonction échoue, je peux pas faire grand chose, mais pas la peine de
vautrer tout le logiciel. Cette exception sera catchée un peu plus haut et
transformée en OperationFailed, l'utilisateur averti et puis c'est tout. Le
log contiendra plus de détails sur l'origine de l'échec (le message associé
au verify()).

En fait, c'est plutôt sur le vocabulaire "assertion" que portait ma
remarque : chez moi une assertion c'est un contrôle qui est *toujours*
vrai quel que soit le contexte d'exécution (entrées utilisateur, ...) et
qui n'est présent qu'en version debug en tant que "auto-controle" du code.

[snip]
Quote:

Au niveau utilisation, vous en pensez quoi ? Je trouve ça bien plus pratique
que ce que j'ai fait jusque là:

if ( value >= 10 )
{
std::ostringstream oss;
oss << "La valeur n'est pas un chiffre : " << value;
throw std::logic_error( oss.str() );
}

Vous faîtes comment vous ?

Je fais pas.
Ce que je veux dire c'est que j'ai l'impression de ne pas connaître de
séquences aussi directes "test->message->on arrête tout"

Back to top
drkm
Guest





PostPosted: Sat Jan 15, 2005 3:06 am    Post subject: Re: [TORDU] Exception dans un destructeur, oui mais... Reply with quote

"Aurélien REGAT-BARREL" <nospam-aregatba (AT) yahoo (DOT) fr.invalid> writes:

Quote:
En gros, est-ce que le code suivant :

[...]

Quote:
est équivalent au niveau de la portée de l'objet retourné à:

Un temporaire est détruit à la fin de l'instruction dans laquelle il
a été créé.

--drkm

Back to top
drkm
Guest





PostPosted: Sat Jan 15, 2005 3:12 am    Post subject: Re: Exception dans un destructeur, oui mais... Reply with quote

"Aurélien REGAT-BARREL" <nospam-aregatba (AT) yahoo (DOT) fr.invalid> writes:

Quote:
j'ai quasiment aucun destructeur (je me
suis converti au RAII).

Huh ?

--drkm

Back to top
James Kanze
Guest





PostPosted: Sat Jan 15, 2005 4:00 pm    Post subject: Re: [TORDU] Exception dans un destructeur, oui mais... Reply with quote

drkm wrote:
Quote:
"Aurélien REGAT-BARREL" <nospam-aregatba (AT) yahoo (DOT) fr.invalid> writes:

Pour cela je me suis dit que verify() pouvait renvoyer une
espèce de flux qui dans son destructeur déclenche une
exception (s'il le faut).

A priori, je dirais que si l'un des opérateurs << lance une
exception, le destructeur du flux sera appelé, et là, BOOM !
ÀMHA, lancer une exception dans un destructeur est extrêmement
délicat.

Il faut pouvoir assurer qu'aucune exception ne sera lancée
entre la création et la destruction de chacune des instances.
Ce qui doit pourvoir néanmoins être fait dans certains cas
particuliers. Dans ce cas-ci, il faudrait imposer que les
surcharges de l'opérateur << pour ce flux ne lancent pas
d'exceptions.

Les règles des opérateurs dans la norme sont assez strictes. Si
la masque des exceptions dans ios interdit les exceptions,
aucune ne doit être lever, y compris dans le cas où le streambuf
en lève un. Si les operator<< sont écrit correctement, ils
atrappent les exceptions, et les mappe en appels à
ios::setstate.

Dans la pratique, fort peu d'opérateurs << (y compris les miens)
sont écrits correctement.

À tout hazard, dans ce cas-ci, je crois que j'emploierais mon
OutputStreamWrapper, modifié de façon à trapper et à ignorer
toute exception (ce qui a aussi l'avantage qu'aucune formattage
n'a lieu s'il n'y a pas de sortie.

Mais encore plus, je me poserais des questions sur l'utilisation
des exceptions dans ce cas-ci. Si j'ai bien compris, il s'agit
d'un genre de assertion, qu'il ne doit jamais y avoir de
l'exception si le programme est correct. Mais si le programme
n'est pas correct, commencer à déballer la pile en executant des
destructeurs sur des objets incohérents, c'est la dernière chose
que je veux faire.

--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Back to top
James Kanze
Guest





PostPosted: Sat Jan 15, 2005 4:14 pm    Post subject: Re: Exception dans un destructeur, oui mais... Reply with quote

Aurélien REGAT-BARREL wrote:
Quote:
Pourquoi lever une exception au lieu de tout arreter si c'est
une assertion ?

Ben l'exception est un bon moyen de tout arrêter proprement
non ?

Proprement, c'est rélatif. L'exception ne peut pas créer la
propreté une fois que c'est partie. En fait, il y a une risque
que les destructeurs l'empire. En fait, quand rien ne va comme
on s'y attendait, un core dump reste ce qu'il y a de plus
propre. Au moins on est sûr de ne pas faire plus de dégats qu'on
n'en a déjà fait.

Et évidemment, appeler abort() s'assure que dans le core dump,
on a tout le contexte pour pouvoir chercher l'erreur. Alors que
si l'exception nettoie la pile...

Quote:
Je compte l'utiliser comme un assert() amélioré certes, mais
pas seulement, aussi voire surtout pour vérifier le code de
retour de fonctions systèmes / d'une bibliothèque tierce
(pilotage d'une caméra scientifique...). Si une telle fonction
échoue, je peux pas faire grand chose, mais pas la peine de
vautrer tout le logiciel. Cette exception sera catchée un peu
plus haut et transformée en OperationFailed, l'utilisateur
averti et puis c'est tout. Le log contiendra plus de détails
sur l'origine de l'échec (le message associé au verify()).

Ce n'est donc pas une véritable assertion.

Peut-être un paramètre supplémentaire à verify, pour signaler la
gravité de l'erreur et donc ce qu'il faut en faire -- avorter
le programme, le traitement en cours (exception) ou continuer
tout simplement.

Quote:
- Si tu utilises ton 'verify' a l'intérieur d'un destructeur,
il faudra prendre garde a rattraper l'exception dans le
destructeur pour ne pas risquer d'avoir une destruction
inachevée.

Peu de risques que cela se produise, j'ai quasiment aucun
destructeur (je me suis converti au RAII).

? RAII, c'est de tout faire dans les destructeurs, plutôt que
dans une logique externe.

Quote:
- Si tu inseres dans ton operator<< le résultat d'une fonction
qui leve une exception, tu auras une 2eme levée d'exception
non rattrapée lors de la destruction de la pile, ce qui est
justement le truc a éviter quand on dit de ne pas lever
d'exception dans un destructeur.

C'est effectivement une possibilité, genre:

verify( value != 0 ) << "La valeur de la classe "
this->getName() << " est nulle.";

si getName() lève une exception je suis mal...
Peu de risques malgré tout, bad_alloc me semble le principal.
Moyennant une bonne doc écrite en rouge clignotant, on devrait
pouvoir s'assurer de la chose.

Au niveau utilisation, vous en pensez quoi ? Je trouve ça bien
plus pratique que ce que j'ai fait jusque là:

if ( value >= 10 )
{
std::ostringstream oss;
oss << "La valeur n'est pas un chiffre : " << value;
throw std::logic_error( oss.str() );
}

Vous faîtes comment vous ?

C'est selon. Pour les asserts, j'ai :
Assert( Ce n'est pas le plus parlant, mais vue que j'ai le core après.

Pour toute la reste, j'ai un loggeur qui renvoie un
OutputStreamWrapper, ce qui permet :

log( Log::fatal ) << "x == " << x << " <--- no go" ;

Si je le veux conditionnel, je peux :

log( x > 10 ? Log::fatal ? Log::info ) << ...

Note bien, en revanche, que fatal finit dans un appel à abort().
Je n'ai rien dans Log qui permettrait de lever une exception
(mais ça serait facile à ajouter -- OutputStreamWrapper utilisee
des callbacks pour l'action en fin des <<).

--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Back to top
James Kanze
Guest





PostPosted: Sat Jan 15, 2005 4:24 pm    Post subject: Re: Exception dans un destructeur, oui mais... Reply with quote

Loïc Joly wrote:
Quote:
Aurélien REGAT-BARREL wrote:

Pourquoi lever une exception au lieu de tout arreter si
c'est une assertion ?

Ben l'exception est un bon moyen de tout arrêter proprement
non ?

Ca se discute. Certains disent qu'en cas d'assert, tu n'es pas
certain de l'état dans lequel tu es, et donc il vaut mieux
arrêter tout au plus vite.

D'autres disent que même si le premier argument est vrai, si
le désagrément causé par un arrêt brutal est relativement
élevé, et si ce qui peut se passer au cas ou le programme
perdre totalement les pédales n'est pas dramatique, vu que la
probalité que ça se passe vraiment mal est assez faible
(estimation sans justification...), il vaut mieux lancer une
exception qui va arrêter calmement le programme.

J'avoue ne pas savoir me situer entre les deux camps.

Ça dépend un peu de l'application, peut-être. Tout ce que je
peux dire, c'est que dans mes applications, la règle à toujours
été de se barrer plutôt que de risquer plus de dégat. Mais il
faut dire qu'en général, j'ai eu un deuxième système en sécours,
qui réprenait la main, et que les dégats que pouvait faire le
programme étaient très élevés. (N'empèche que j'ai l'impression
que c'est une bonne règle de base. À condition de se rappeler
qu'il faut vérifier dans chaque application qu'on n'a pas
affaire à une exception.)

Quote:
Vous faîtes comment vous ?

Je ne fais pas, mais je me demande si un truc tordu comme le
suivant pourrait marcher :

class DoOnceAndThrow
{
DoOnceAndThrow() isAlreadyDone(false) {}
void tryToDoIt()
{
if (isAlreadyDone)
throw std::exception;
isAlreadyDone = true;
}
bool isAlreadyDone;
}

#define verify(b)
DoOnceAndThrow doat##__LINE__; // 1
if (b) ; // 2
else
while(doOnceAndThrow())
log

// 1 : Pour essayer de ne pas avoir deux identificateurs
portant le même nom dans la même portée. Ne marchera que s'il
n'y a pas 2 verifie sur une seule ligne

// 2 : Permet d'éviter des trucs étranges si verifie est appelé dans un
if qui comporte un else, par exemple.

Et ça doit faire quoi, exactement ? Je ne comprends rien du code
dans le macro.

Et évidemment, ton if/else ne sert à rien ici. Parce que si
j'écris :

if ( a > b )
verify( c > b ) << ... ;

il n'y aurait que la declaration de doat##__LINE__ qui se trouve
dans l'if ; le if/else est une deuxième instruction. (Et si
j'ajoute un else à mon if, ci-dessus, ça ne compile même pas.

--
James Kanze home: www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 pl. Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.