// 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.
Je pressentais bien qu'une excception dans un destructeur n'était pas une bonne idée,
pas forcement.
Sans doute. Je ne vois pas de cas particulier où cela se justifierait, mais je manque d'imaginiation.
mais je ne trouvais rien à ce sujet.
voir uncaught_exception().
Mais si je comprend bien, lorsqu'une exception est levée, les destructeurs des objets automatiques dans la portée sont appelés, *avant* le gestionnaire d'exception (le cas du PO) ou `uncaught_exception()'.
Cfr. la conclusion de <URL:http://www.gotw.ca/gotw/047.htm> :
3. Is there any other good use for uncaught_exception? Discuss and draw conclusions.
Unfortunately, I do not know of any good and safe use for std::uncaught_exception. My advice: Don't use it.
--drkm
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
bernard tatin wrote:
Je pressentais bien qu'une excception dans un destructeur n'était
pas une bonne idée,
pas forcement.
Sans doute. Je ne vois pas de cas particulier où cela se
justifierait, mais je manque d'imaginiation.
mais je ne trouvais rien à ce sujet.
voir uncaught_exception().
Mais si je comprend bien, lorsqu'une exception est levée, les
destructeurs des objets automatiques dans la portée sont appelés,
*avant* le gestionnaire d'exception (le cas du PO) ou
`uncaught_exception()'.
Cfr. la conclusion de <URL:http://www.gotw.ca/gotw/047.htm> :
3. Is there any other good use for uncaught_exception? Discuss and
draw conclusions.
Unfortunately, I do not know of any good and safe use for
std::uncaught_exception. My advice: Don't use it.
Je pressentais bien qu'une excception dans un destructeur n'était pas une bonne idée,
pas forcement.
Sans doute. Je ne vois pas de cas particulier où cela se justifierait, mais je manque d'imaginiation.
mais je ne trouvais rien à ce sujet.
voir uncaught_exception().
Mais si je comprend bien, lorsqu'une exception est levée, les destructeurs des objets automatiques dans la portée sont appelés, *avant* le gestionnaire d'exception (le cas du PO) ou `uncaught_exception()'.
Cfr. la conclusion de <URL:http://www.gotw.ca/gotw/047.htm> :
3. Is there any other good use for uncaught_exception? Discuss and draw conclusions.
Unfortunately, I do not know of any good and safe use for std::uncaught_exception. My advice: Don't use it.
--drkm
Fabien LE LEZ
On Wed, 27 Oct 2004 17:41:51 +0200, bernard tatin :
Depuis tout à l'heure, je viens de trouver deux autres configurations qui me mettent dans cette situation.
De deux choses l'une : - soit une fonction appelée dans un destructeur peut légitimement lancer une exception, auquel cas le destructeur doit comporter un bloc try...catch - soit l'exception lancée par le destructeur vient d'une erreur de programmation, et le fait que le programme s'arrête carrément n'est pas gênant, car ce bug n'existera plus à la fin de la phase de développement.
-- ;-)
On Wed, 27 Oct 2004 17:41:51 +0200, bernard tatin
<bernard.tatin@nospam.tele2.fr>:
Depuis tout à l'heure, je viens de trouver deux autres configurations
qui me mettent dans cette situation.
De deux choses l'une :
- soit une fonction appelée dans un destructeur peut
légitimement lancer une exception, auquel cas le destructeur doit
comporter un bloc try...catch
- soit l'exception lancée par le destructeur vient d'une erreur
de programmation, et le fait que le programme s'arrête carrément n'est
pas gênant, car ce bug n'existera plus à la fin de la phase de
développement.
On Wed, 27 Oct 2004 17:41:51 +0200, bernard tatin :
Depuis tout à l'heure, je viens de trouver deux autres configurations qui me mettent dans cette situation.
De deux choses l'une : - soit une fonction appelée dans un destructeur peut légitimement lancer une exception, auquel cas le destructeur doit comporter un bloc try...catch - soit l'exception lancée par le destructeur vient d'une erreur de programmation, et le fait que le programme s'arrête carrément n'est pas gênant, car ce bug n'existera plus à la fin de la phase de développement.
-- ;-)
Fabien LE LEZ
On Wed, 27 Oct 2004 18:27:15 +0200, drkm :
Unfortunately, I do not know of any good and safe use for std::uncaught_exception. My advice: Don't use it.
En lisant Herb Sutter, on s'aperçoit qu'un sacré paquet de fonctionnalités de C++ sont inutiles[*] ;-)
[*] à commencer par "export", même s'il est moins catégorique sur cet exemple.
-- ;-)
On Wed, 27 Oct 2004 18:27:15 +0200, drkm <usenet.fclcxx@fgeorges.org>:
Unfortunately, I do not know of any good and safe use for
std::uncaught_exception. My advice: Don't use it.
En lisant Herb Sutter, on s'aperçoit qu'un sacré paquet de
fonctionnalités de C++ sont inutiles[*] ;-)
[*] à commencer par "export", même s'il est moins catégorique sur cet
exemple.
Unfortunately, I do not know of any good and safe use for std::uncaught_exception. My advice: Don't use it.
En lisant Herb Sutter, on s'aperçoit qu'un sacré paquet de fonctionnalités de C++ sont inutiles[*] ;-)
[*] à commencer par "export", même s'il est moins catégorique sur cet exemple.
-- ;-)
Loïc Joly
Fabien LE LEZ wrote:
On Wed, 27 Oct 2004 15:10:53 +0200, bernard tatin :
L'exit est suffisament brutal pour que le serveur de socket d'en face soit souvent obligé de ne réagir que sur un time-out.
D'un autre côté, c'est sensé n'arriver qu'exceptionnellement, dans des cas où il n'est même pas sûr que l'OS soit encore dans un état assez stable pour fermer une connexion TCP.
En fait, il y a deux écoles : - Ceux qui disent que l'on ne peut plus rien prévoir, et alors, autant tout arrêter au plus vite. - Ceux qui disent que malgré tout, il y a une chance que ça fasse quand même quelquechose de correct, alors autant tenter de le faire, même si ça peut donner une fausse impression de sécurité.
-- Loïc
Fabien LE LEZ wrote:
On Wed, 27 Oct 2004 15:10:53 +0200, bernard tatin
<bernard.tatin@nospam.tele2.fr>:
L'exit est suffisament brutal pour que le serveur de
socket d'en face soit souvent obligé de ne réagir que sur un time-out.
D'un autre côté, c'est sensé n'arriver qu'exceptionnellement, dans des
cas où il n'est même pas sûr que l'OS soit encore dans un état assez
stable pour fermer une connexion TCP.
En fait, il y a deux écoles :
- Ceux qui disent que l'on ne peut plus rien prévoir, et alors, autant
tout arrêter au plus vite.
- Ceux qui disent que malgré tout, il y a une chance que ça fasse quand
même quelquechose de correct, alors autant tenter de le faire, même si
ça peut donner une fausse impression de sécurité.
On Wed, 27 Oct 2004 15:10:53 +0200, bernard tatin :
L'exit est suffisament brutal pour que le serveur de socket d'en face soit souvent obligé de ne réagir que sur un time-out.
D'un autre côté, c'est sensé n'arriver qu'exceptionnellement, dans des cas où il n'est même pas sûr que l'OS soit encore dans un état assez stable pour fermer une connexion TCP.
En fait, il y a deux écoles : - Ceux qui disent que l'on ne peut plus rien prévoir, et alors, autant tout arrêter au plus vite. - Ceux qui disent que malgré tout, il y a une chance que ça fasse quand même quelquechose de correct, alors autant tenter de le faire, même si ça peut donner une fausse impression de sécurité.
-- Loïc
Fabien LE LEZ
On Wed, 27 Oct 2004 20:47:10 +0200, Loïc Joly :
Ceux qui disent que malgré tout, il y a une chance que ça fasse quand même quelquechose de correct, alors autant tenter de le faire
... en essayant de s'assurer tout de même que ça ne fera pas quelque chose de catastrophique :/
-- ;-)
On Wed, 27 Oct 2004 20:47:10 +0200, Loïc Joly
<loic.actarus.joly@wanadoo.fr>:
Ceux qui disent que malgré tout, il y a une chance que ça fasse quand
même quelquechose de correct, alors autant tenter de le faire
... en essayant de s'assurer tout de même que ça ne fera pas quelque
chose de catastrophique :/
Ceux qui disent que malgré tout, il y a une chance que ça fasse quand même quelquechose de correct, alors autant tenter de le faire
... en essayant de s'assurer tout de même que ça ne fera pas quelque chose de catastrophique :/
-- ;-)
bernard tatin
Jean-Marc Bourguet wrote:
Un timeout de 2 minutes sur le serveur de temps en temps pendant la periode de developpement (puisque ca ne devrait jamais arriver) pose probleme? C'est quoi votre structure?
A+
Mon (petit) projet c'est d'abord me remettre au C++ que je n'ai pas
vraiment pratiqué depuis quelques années. J'ai perdu un peu la main d'autant plus que j'ai fait beaucoup de Java (pour manger) et de Lisp (pour jouer). Ensuite, c'est tenter de maîtriser la programmation réseau sous Unix (MacOS X, mais ça marche aussi sous FreeBSD et un peu Linux, mais là je ne peux pas bien tester). Je fais des choses qui existent et qui marchent mieux ailleurs, mais je reprend point par point la programmation réseau et j'apprends. J'apprends la manipulation des noms d'hôtes, des protocoles autres que TCP et UDP... à construire une trame IP complète et l'envoyer...
J'ai un premier ensemble de classes pour traiter le protocole ICMP. Je cherche à gérer toutes les erreurs par des exceptions, d'où mes déconvenues premières.
J'ai un second ensemble de classes pour un protocole d'échange de données en TCP. Je ne sais pas si j'arriverais au bout, le temps dont je dispose n'est pas extensible, mais le but est de faire un ensemble de classes pour du calcul distribué sur plusieurs machine - je sais que c'est ambitieux. Je ne ferais pas mieux ce que d'autres ont déjà fait, mais en le faisant j'ai déjà (ré)appris beaucoup de choses. Dans le cas de ce système client serveur, j'essaie de limiter le plus possible l'utilisation des resources côté communication. Et ces dernières heures, avec mes tests, j'ai pu voir que la gestion des erreurs sur les sockets est vraiment complexe. A quel moment puis-je reprendre la communication, à quel moment suis-je obliger de couper et de recommencer ? J'avais beaucoup espéré sur mon exception lancée depuis le destructeur. Je dois revoir mon architecture pour m'en dépétrer.
Voilà donc l'histoire complète.
Bernard.
Jean-Marc Bourguet wrote:
Un timeout de 2 minutes sur le serveur de temps en temps pendant la
periode de developpement (puisque ca ne devrait jamais arriver) pose
probleme? C'est quoi votre structure?
A+
Mon (petit) projet c'est d'abord me remettre au C++ que je n'ai pas
vraiment pratiqué depuis quelques années. J'ai perdu un peu la main
d'autant plus que j'ai fait beaucoup de Java (pour manger) et de Lisp
(pour jouer). Ensuite, c'est tenter de maîtriser la programmation réseau
sous Unix (MacOS X, mais ça marche aussi sous FreeBSD et un peu Linux,
mais là je ne peux pas bien tester). Je fais des choses qui existent et
qui marchent mieux ailleurs, mais je reprend point par point la
programmation réseau et j'apprends. J'apprends la manipulation des noms
d'hôtes, des protocoles autres que TCP et UDP... à construire une trame
IP complète et l'envoyer...
J'ai un premier ensemble de classes pour traiter le protocole ICMP. Je
cherche à gérer toutes les erreurs par des exceptions, d'où mes
déconvenues premières.
J'ai un second ensemble de classes pour un protocole d'échange de
données en TCP. Je ne sais pas si j'arriverais au bout, le temps dont je
dispose n'est pas extensible, mais le but est de faire un ensemble de
classes pour du calcul distribué sur plusieurs machine - je sais que
c'est ambitieux. Je ne ferais pas mieux ce que d'autres ont déjà fait,
mais en le faisant j'ai déjà (ré)appris beaucoup de choses. Dans le cas
de ce système client serveur, j'essaie de limiter le plus possible
l'utilisation des resources côté communication. Et ces dernières heures,
avec mes tests, j'ai pu voir que la gestion des erreurs sur les sockets
est vraiment complexe. A quel moment puis-je reprendre la communication,
à quel moment suis-je obliger de couper et de recommencer ? J'avais
beaucoup espéré sur mon exception lancée depuis le destructeur. Je dois
revoir mon architecture pour m'en dépétrer.
Un timeout de 2 minutes sur le serveur de temps en temps pendant la periode de developpement (puisque ca ne devrait jamais arriver) pose probleme? C'est quoi votre structure?
A+
Mon (petit) projet c'est d'abord me remettre au C++ que je n'ai pas
vraiment pratiqué depuis quelques années. J'ai perdu un peu la main d'autant plus que j'ai fait beaucoup de Java (pour manger) et de Lisp (pour jouer). Ensuite, c'est tenter de maîtriser la programmation réseau sous Unix (MacOS X, mais ça marche aussi sous FreeBSD et un peu Linux, mais là je ne peux pas bien tester). Je fais des choses qui existent et qui marchent mieux ailleurs, mais je reprend point par point la programmation réseau et j'apprends. J'apprends la manipulation des noms d'hôtes, des protocoles autres que TCP et UDP... à construire une trame IP complète et l'envoyer...
J'ai un premier ensemble de classes pour traiter le protocole ICMP. Je cherche à gérer toutes les erreurs par des exceptions, d'où mes déconvenues premières.
J'ai un second ensemble de classes pour un protocole d'échange de données en TCP. Je ne sais pas si j'arriverais au bout, le temps dont je dispose n'est pas extensible, mais le but est de faire un ensemble de classes pour du calcul distribué sur plusieurs machine - je sais que c'est ambitieux. Je ne ferais pas mieux ce que d'autres ont déjà fait, mais en le faisant j'ai déjà (ré)appris beaucoup de choses. Dans le cas de ce système client serveur, j'essaie de limiter le plus possible l'utilisation des resources côté communication. Et ces dernières heures, avec mes tests, j'ai pu voir que la gestion des erreurs sur les sockets est vraiment complexe. A quel moment puis-je reprendre la communication, à quel moment suis-je obliger de couper et de recommencer ? J'avais beaucoup espéré sur mon exception lancée depuis le destructeur. Je dois revoir mon architecture pour m'en dépétrer.
Voilà donc l'histoire complète.
Bernard.
Gabriel Dos Reis
Fabien LE LEZ writes:
| On Wed, 27 Oct 2004 18:27:15 +0200, drkm : | | > Unfortunately, I do not know of any good and safe use for | > std::uncaught_exception. My advice: Don't use it. | | En lisant Herb Sutter, on s'aperçoit qu'un sacré paquet de | fonctionnalités de C++ sont inutiles[*] ;-) | | [*] à commencer par "export", même s'il est moins catégorique sur cet | exemple.
Je regrette que le dernier XC++ soit encore aussi anti-export. :-(
-- Gaby
Fabien LE LEZ <gramster@gramster.com> writes:
| On Wed, 27 Oct 2004 18:27:15 +0200, drkm <usenet.fclcxx@fgeorges.org>:
|
| > Unfortunately, I do not know of any good and safe use for
| > std::uncaught_exception. My advice: Don't use it.
|
| En lisant Herb Sutter, on s'aperçoit qu'un sacré paquet de
| fonctionnalités de C++ sont inutiles[*] ;-)
|
| [*] à commencer par "export", même s'il est moins catégorique sur cet
| exemple.
Je regrette que le dernier XC++ soit encore aussi anti-export. :-(
| On Wed, 27 Oct 2004 18:27:15 +0200, drkm : | | > Unfortunately, I do not know of any good and safe use for | > std::uncaught_exception. My advice: Don't use it. | | En lisant Herb Sutter, on s'aperçoit qu'un sacré paquet de | fonctionnalités de C++ sont inutiles[*] ;-) | | [*] à commencer par "export", même s'il est moins catégorique sur cet | exemple.
Je regrette que le dernier XC++ soit encore aussi anti-export. :-(
-- Gaby
kanze
Andre Heinen wrote in message news:...
On 27 Oct 2004 15:18:09 +0200, Jean-Marc Bourguet wrote:
Depuis quand on enleve les gilets de sauvetage quand on part en mer?
Si tu refuses d'enlever ton gilet de sauvetage quand tu pars en mer, il est d'autant plus important de ne jamais utiliser assert(), puisqu'elle ne sera pas compilée dans les versions release...
Selon la norme, assert serait compilé sauf si le macro NDEBUG est défini. C'est à toi de décider si c'est défini dans les les versions de release ou non. (C'est effectivement défini par défaut dans les makefiles pour le build release sous Visual Studios. Mais c'est trivial de les changer -- et puisque de toute façon, tu vas vérifier que tout est comme tu veux pour la release, tu le changes dans la foulée.)
En fait, dans des projets sérieux, je me suis prèsque toujours servi de mon propre assert. Afin de définir mes messages d'erreur moi-même, m'assurer qu'ils aillent vers le log, etc. Mais la principe est la même (et je me servais de NDEBUG de la même façon que dans assert).
Personnellement il m'est arrivé de coder des assert() qui ralentissaient considérablement le programme. Dans ce cas, c'est un mécanisme pratique. Quand tu testes, tant pis si le programme est plus lent: tu veux tout vérifier. A partir du moment où tu as le sentiment de ne plus (trop) courir de risque, tu définis NDEBUG, les assert() disparaissent, et le code devient suffisamment rapide pour être mis en production.
Il arrive des cas où effectivement, le profiler montre qu'il faut virer l'assert() (ou tout autre code de vérification). Dans ce cas-là (et seulement dans ce cas-là), on écrit quelque chose du genre :
#ifdef PRODUCTION #define NDEBUG #endif #include <assert.h>
// Fonction avec le code critique...
#undef NDEBUG #include <assert.h>
Si le comité C a exigé que l'inclusion multiple de <assert.h> fonction, il y a bien une raison.
-- James Kanze GABI Software http://www.gabi-soft.fr 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
Andre Heinen <nospam@nospam.invalid> wrote in message
news:<n89vn0ps42jhs37s7uuku7b87e88tgalmd@4ax.com>...
On 27 Oct 2004 15:18:09 +0200, Jean-Marc Bourguet
<jm@bourguet.org> wrote:
Depuis quand on enleve les gilets de sauvetage quand on part en mer?
Si tu refuses d'enlever ton gilet de sauvetage quand tu pars en mer,
il est d'autant plus important de ne jamais utiliser assert(),
puisqu'elle ne sera pas compilée dans les versions release...
Selon la norme, assert serait compilé sauf si le macro NDEBUG est
défini. C'est à toi de décider si c'est défini dans les les versions de
release ou non. (C'est effectivement défini par défaut dans les
makefiles pour le build release sous Visual Studios. Mais c'est trivial
de les changer -- et puisque de toute façon, tu vas vérifier que tout
est comme tu veux pour la release, tu le changes dans la foulée.)
En fait, dans des projets sérieux, je me suis prèsque toujours servi de
mon propre assert. Afin de définir mes messages d'erreur moi-même,
m'assurer qu'ils aillent vers le log, etc. Mais la principe est la même
(et je me servais de NDEBUG de la même façon que dans assert).
Personnellement il m'est arrivé de coder des assert() qui
ralentissaient considérablement le programme. Dans ce cas, c'est un
mécanisme pratique. Quand tu testes, tant pis si le programme est plus
lent: tu veux tout vérifier. A partir du moment où tu as le sentiment
de ne plus (trop) courir de risque, tu définis NDEBUG, les assert()
disparaissent, et le code devient suffisamment rapide pour être mis en
production.
Il arrive des cas où effectivement, le profiler montre qu'il faut virer
l'assert() (ou tout autre code de vérification). Dans ce cas-là (et
seulement dans ce cas-là), on écrit quelque chose du genre :
#ifdef PRODUCTION
#define NDEBUG
#endif
#include <assert.h>
// Fonction avec le code critique...
#undef NDEBUG
#include <assert.h>
Si le comité C a exigé que l'inclusion multiple de <assert.h> fonction,
il y a bien une raison.
--
James Kanze GABI Software http://www.gabi-soft.fr
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 27 Oct 2004 15:18:09 +0200, Jean-Marc Bourguet wrote:
Depuis quand on enleve les gilets de sauvetage quand on part en mer?
Si tu refuses d'enlever ton gilet de sauvetage quand tu pars en mer, il est d'autant plus important de ne jamais utiliser assert(), puisqu'elle ne sera pas compilée dans les versions release...
Selon la norme, assert serait compilé sauf si le macro NDEBUG est défini. C'est à toi de décider si c'est défini dans les les versions de release ou non. (C'est effectivement défini par défaut dans les makefiles pour le build release sous Visual Studios. Mais c'est trivial de les changer -- et puisque de toute façon, tu vas vérifier que tout est comme tu veux pour la release, tu le changes dans la foulée.)
En fait, dans des projets sérieux, je me suis prèsque toujours servi de mon propre assert. Afin de définir mes messages d'erreur moi-même, m'assurer qu'ils aillent vers le log, etc. Mais la principe est la même (et je me servais de NDEBUG de la même façon que dans assert).
Personnellement il m'est arrivé de coder des assert() qui ralentissaient considérablement le programme. Dans ce cas, c'est un mécanisme pratique. Quand tu testes, tant pis si le programme est plus lent: tu veux tout vérifier. A partir du moment où tu as le sentiment de ne plus (trop) courir de risque, tu définis NDEBUG, les assert() disparaissent, et le code devient suffisamment rapide pour être mis en production.
Il arrive des cas où effectivement, le profiler montre qu'il faut virer l'assert() (ou tout autre code de vérification). Dans ce cas-là (et seulement dans ce cas-là), on écrit quelque chose du genre :
#ifdef PRODUCTION #define NDEBUG #endif #include <assert.h>
// Fonction avec le code critique...
#undef NDEBUG #include <assert.h>
Si le comité C a exigé que l'inclusion multiple de <assert.h> fonction, il y a bien une raison.
-- James Kanze GABI Software http://www.gabi-soft.fr 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
kanze
Jean-Marc Bourguet wrote in message news:...
Andre Heinen writes:
On 27 Oct 2004 15:18:09 +0200, Jean-Marc Bourguet wrote:
Depuis quand on enleve les gilets de sauvetage quand on part en mer?
Si tu refuses d'enlever ton gilet de sauvetage quand tu pars en mer, il est d'autant plus important de ne jamais utiliser assert(), puisqu'elle ne sera pas compilée dans les versions release...
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.
-- James Kanze GABI Software http://www.gabi-soft.fr 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
Jean-Marc Bourguet <jm@bourguet.org> wrote in message
news:<pxbmzy8i7qw.fsf@news.bourguet.org>...
Andre Heinen <nospam@nospam.invalid> writes:
On 27 Oct 2004 15:18:09 +0200, Jean-Marc Bourguet
<jm@bourguet.org> wrote:
Depuis quand on enleve les gilets de sauvetage quand on part en mer?
Si tu refuses d'enlever ton gilet de sauvetage quand tu pars en mer,
il est d'autant plus important de ne jamais utiliser assert(),
puisqu'elle ne sera pas compilée dans les versions release...
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.
--
James Kanze GABI Software http://www.gabi-soft.fr
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 27 Oct 2004 15:18:09 +0200, Jean-Marc Bourguet wrote:
Depuis quand on enleve les gilets de sauvetage quand on part en mer?
Si tu refuses d'enlever ton gilet de sauvetage quand tu pars en mer, il est d'autant plus important de ne jamais utiliser assert(), puisqu'elle ne sera pas compilée dans les versions release...
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.
-- James Kanze GABI Software http://www.gabi-soft.fr 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
kanze
Marc Boyer wrote in message news:<clobap$4f9$...
Ca, ça montre surtout que assert est trop simpliste pour un contexte professionnel.
Pourquoi?
Pour moi, une macro chargée de vérifier des invariants devrait 1) donner plus d'info que le simple couple __LINE__ / __FILE__ par défaut (__fun__ aussi, puis un numéro de version)
Ce n'est pas l'absense de __fun__ (par exemple) qui me gène. C'est que le message ne peut pas s'adopter selon la destination. Donc, par exemple, si c'est quelque part où l'utilisateur le voit (ce qui n'est pas sans intérêt), ce qu'il faut, c'est quelque chose du genre :
INTERNAL : veuillez contacter le service après-vente, en leur envoyant le fichier core que tu trouveras dans ..., ainsi que les informations suivantes :
produit : ... version : ...
ainsi qu'une description de ce que vous étiez en train de faire.
Si j'ai le core, je n'ai pas besoin de __LINE__/__FILE__. En revanche, __LINE__, __FILE__ et même __fun__ ne me servent à rien si je ne connais pas la version.
Évidemment, dans les applications internes, le message est plus simple, simplement un texte pour dire qu'il y a eu un problème, et qu'il faut rédémarrer le programme. Parce que le macro aurait envoyé un email avec les informations pertinantes à la bonne adresse tout seul. (Dans la plupart des applications, l'application que voit l'utilisateur n'est en fait qu'un script assez simple, qui reconnaît que le programme est sortie d'une façon anormale, et le rélance. Et c'est le script qui envoie l'email, aussi, en y incorporant le core.)
2) permette d'activer/désactiver de manière plus fine les invariant (notion de groupe et d'identité), permettre des choses du genre gcc -DNO_PRECOND(foo) pour virer les preconditions de la fonction foo gcc -DNO_GROUP_PRECOND(overflow) pour virer globalement les tests d'overflow
Là ce que tu démande, ce n'est plus simplement assert, mais un système complet de gestion des log. Où, d'ailleurs, c'est plus intéressant d'avoir une configuration dynamique -- pour résoudre un problème chez un client, tu vas avoir besoin peut-être des traces supplémentaire, mais tu ne veux certainement pas installer un nouveau binaire. (Dans le cas des serveurs, je m'arrange même en général pour pouvoir changer la configuration de trace sans arrêter le serveur.)
3) le fait de simplement écrire dans stderr n'est pas forcément ce qu'on attend, on peut vouloir un peu plus, non ?
Surtout dans le cas des serveurs, où stderr est attaché à /dev/null.
Ce genre de choses, non ?
N'importe quelle application sérieuse aurait une gestion de log configurable. En général, c'est effectivement intéressant que assert s'y integre.
Dans la pratique (et je sais que c'est formellement un comportement indéfini), on peut fournir son propre fichier assert.h, de façon à ratrapper après coup. Dans les grands projets (c-à-d, ceux qui sont reconnu grand dès le départ), on définit une gestion de log avant de commencer, dont on se sert à la place d'assert.
-- James Kanze GABI Software http://www.gabi-soft.fr 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 Boyer <Marc.Boyer@enseeiht.yahoo.fr.invalid> wrote in message
news:<clobap$4f9$1@news.cict.fr>...
Ca, ça montre surtout que assert est trop simpliste pour un
contexte professionnel.
Pourquoi?
Pour moi, une macro chargée de vérifier des invariants devrait
1) donner plus d'info que le simple couple __LINE__ / __FILE__
par défaut (__fun__ aussi, puis un numéro de version)
Ce n'est pas l'absense de __fun__ (par exemple) qui me gène. C'est que
le message ne peut pas s'adopter selon la destination. Donc, par
exemple, si c'est quelque part où l'utilisateur le voit (ce qui n'est
pas sans intérêt), ce qu'il faut, c'est quelque chose du genre :
INTERNAL : veuillez contacter le service après-vente, en leur
envoyant le fichier core que tu trouveras dans ...,
ainsi que les informations suivantes :
produit : ...
version : ...
ainsi qu'une description de ce que vous étiez en
train de faire.
Si j'ai le core, je n'ai pas besoin de __LINE__/__FILE__. En revanche,
__LINE__, __FILE__ et même __fun__ ne me servent à rien si je ne connais
pas la version.
Évidemment, dans les applications internes, le message est plus simple,
simplement un texte pour dire qu'il y a eu un problème, et qu'il faut
rédémarrer le programme. Parce que le macro aurait envoyé un email avec
les informations pertinantes à la bonne adresse tout seul. (Dans la
plupart des applications, l'application que voit l'utilisateur n'est en
fait qu'un script assez simple, qui reconnaît que le programme est
sortie d'une façon anormale, et le rélance. Et c'est le script qui
envoie l'email, aussi, en y incorporant le core.)
2) permette d'activer/désactiver de manière plus fine
les invariant (notion de groupe et d'identité), permettre
des choses du genre
gcc -DNO_PRECOND(foo)
pour virer les preconditions de la fonction foo
gcc -DNO_GROUP_PRECOND(overflow)
pour virer globalement les tests d'overflow
Là ce que tu démande, ce n'est plus simplement assert, mais un système
complet de gestion des log. Où, d'ailleurs, c'est plus intéressant
d'avoir une configuration dynamique -- pour résoudre un problème chez un
client, tu vas avoir besoin peut-être des traces supplémentaire, mais tu
ne veux certainement pas installer un nouveau binaire. (Dans le cas des
serveurs, je m'arrange même en général pour pouvoir changer la
configuration de trace sans arrêter le serveur.)
3) le fait de simplement écrire dans stderr n'est pas
forcément ce qu'on attend, on peut vouloir un peu
plus, non ?
Surtout dans le cas des serveurs, où stderr est attaché à /dev/null.
Ce genre de choses, non ?
N'importe quelle application sérieuse aurait une gestion de log
configurable. En général, c'est effectivement intéressant que assert s'y
integre.
Dans la pratique (et je sais que c'est formellement un comportement
indéfini), on peut fournir son propre fichier assert.h, de façon à
ratrapper après coup. Dans les grands projets (c-à-d, ceux qui sont
reconnu grand dès le départ), on définit une gestion de log avant de
commencer, dont on se sert à la place d'assert.
--
James Kanze GABI Software http://www.gabi-soft.fr
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
Ca, ça montre surtout que assert est trop simpliste pour un contexte professionnel.
Pourquoi?
Pour moi, une macro chargée de vérifier des invariants devrait 1) donner plus d'info que le simple couple __LINE__ / __FILE__ par défaut (__fun__ aussi, puis un numéro de version)
Ce n'est pas l'absense de __fun__ (par exemple) qui me gène. C'est que le message ne peut pas s'adopter selon la destination. Donc, par exemple, si c'est quelque part où l'utilisateur le voit (ce qui n'est pas sans intérêt), ce qu'il faut, c'est quelque chose du genre :
INTERNAL : veuillez contacter le service après-vente, en leur envoyant le fichier core que tu trouveras dans ..., ainsi que les informations suivantes :
produit : ... version : ...
ainsi qu'une description de ce que vous étiez en train de faire.
Si j'ai le core, je n'ai pas besoin de __LINE__/__FILE__. En revanche, __LINE__, __FILE__ et même __fun__ ne me servent à rien si je ne connais pas la version.
Évidemment, dans les applications internes, le message est plus simple, simplement un texte pour dire qu'il y a eu un problème, et qu'il faut rédémarrer le programme. Parce que le macro aurait envoyé un email avec les informations pertinantes à la bonne adresse tout seul. (Dans la plupart des applications, l'application que voit l'utilisateur n'est en fait qu'un script assez simple, qui reconnaît que le programme est sortie d'une façon anormale, et le rélance. Et c'est le script qui envoie l'email, aussi, en y incorporant le core.)
2) permette d'activer/désactiver de manière plus fine les invariant (notion de groupe et d'identité), permettre des choses du genre gcc -DNO_PRECOND(foo) pour virer les preconditions de la fonction foo gcc -DNO_GROUP_PRECOND(overflow) pour virer globalement les tests d'overflow
Là ce que tu démande, ce n'est plus simplement assert, mais un système complet de gestion des log. Où, d'ailleurs, c'est plus intéressant d'avoir une configuration dynamique -- pour résoudre un problème chez un client, tu vas avoir besoin peut-être des traces supplémentaire, mais tu ne veux certainement pas installer un nouveau binaire. (Dans le cas des serveurs, je m'arrange même en général pour pouvoir changer la configuration de trace sans arrêter le serveur.)
3) le fait de simplement écrire dans stderr n'est pas forcément ce qu'on attend, on peut vouloir un peu plus, non ?
Surtout dans le cas des serveurs, où stderr est attaché à /dev/null.
Ce genre de choses, non ?
N'importe quelle application sérieuse aurait une gestion de log configurable. En général, c'est effectivement intéressant que assert s'y integre.
Dans la pratique (et je sais que c'est formellement un comportement indéfini), on peut fournir son propre fichier assert.h, de façon à ratrapper après coup. Dans les grands projets (c-à-d, ceux qui sont reconnu grand dès le départ), on définit une gestion de log avant de commencer, dont on se sert à la place d'assert.
-- James Kanze GABI Software http://www.gabi-soft.fr 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