je souhaite créer des exceptions en les dérivant de std::exception, mais
je me fais agonir d'injures à l'édition de liens par g++ quant à leur
méthode what() et à leur destructeur, quand je n'utilise pas le mot clé
throw.
Je croyais que le mot clé throw servait à déclarer quelles exceptions la
méthode concernée était susceptible de lever, je constate qu'il n'en
est rien, mais je ne vois vraiment pas ce que le throw utilisé dans ce
contexte peut signifier.
On Tue, 03 Jan 2006 17:31:40 +0100, Brieuc Jeunhomme :
je souhaite créer des exceptions en les dérivant de std::exception, mais je me fais agonir d'injures à l'édition de liens par g++ quant à leur méthode what() et à leur destructeur, quand je n'utilise pas le mot clé throw.
Dans le prototype de la fonction, tu veux dire ?
C'est normal : le "throw()" fait partie du prototype de la fonction. Si tu déclares une fonction membre what() avec un autre prototype, ça cache la fonction std::exception::what() au lieu de la remplacer.
Je croyais que le mot clé throw servait à déclarer quelles exceptions la méthode concernée était susceptible de lever,
C'est bien ça.
je constate qu'il n'en est rien,
Ben si. Le "throw()" indique que what() ne lance jamais d'exception.
On Tue, 03 Jan 2006 17:31:40 +0100, Brieuc Jeunhomme
<brieuc.jeunhomme@gmail.com>:
je souhaite créer des exceptions en les dérivant de std::exception, mais
je me fais agonir d'injures à l'édition de liens par g++ quant à leur
méthode what() et à leur destructeur, quand je n'utilise pas le mot clé
throw.
Dans le prototype de la fonction, tu veux dire ?
C'est normal : le "throw()" fait partie du prototype de la fonction.
Si tu déclares une fonction membre what() avec un autre prototype, ça
cache la fonction std::exception::what() au lieu de la remplacer.
On Tue, 03 Jan 2006 17:31:40 +0100, Brieuc Jeunhomme :
je souhaite créer des exceptions en les dérivant de std::exception, mais je me fais agonir d'injures à l'édition de liens par g++ quant à leur méthode what() et à leur destructeur, quand je n'utilise pas le mot clé throw.
Dans le prototype de la fonction, tu veux dire ?
C'est normal : le "throw()" fait partie du prototype de la fonction. Si tu déclares une fonction membre what() avec un autre prototype, ça cache la fonction std::exception::what() au lieu de la remplacer.
Je croyais que le mot clé throw servait à déclarer quelles exceptions la méthode concernée était susceptible de lever,
C'est bien ça.
je constate qu'il n'en est rien,
Ben si. Le "throw()" indique que what() ne lance jamais d'exception.
Brieuc Jeunhomme
mais je me fais agonir d'injures à l'édition de liens par g++ quant à leur méthode what() et à leur destructeur, quand je n'utilise pas le mot clé throw.
Dans le prototype de la fonction, tu veux dire ?
Oui.
C'est normal : le "throw()" fait partie du prototype de la fonction. Si tu déclares une fonction membre what() avec un autre prototype, ça cache la fonction std::exception::what() au lieu de la remplacer.
Je croyais que le mot clé throw servait à déclarer quelles exceptions la méthode concernée était susceptible de lever,
C'est bien ça.
je constate qu'il n'en est rien,
Ben si. Le "throw()" indique que what() ne lance jamais d'exception.
Dans ces conditions, c'est à mon avis dommage que le compilateur accepte un code comme celui-ci:
struct foo {
void bar() throw () { int *p = new int; delete p; }
};
Ou peut-être existe-t-il un intérêt à la chose que je n'ai pas saisi ?
-- BBP
mais je me fais agonir d'injures à l'édition de liens par g++ quant à
leur méthode what() et à leur destructeur, quand je n'utilise pas le
mot clé throw.
Dans le prototype de la fonction, tu veux dire ?
Oui.
C'est normal : le "throw()" fait partie du prototype de la fonction.
Si tu déclares une fonction membre what() avec un autre prototype, ça
cache la fonction std::exception::what() au lieu de la remplacer.
mais je me fais agonir d'injures à l'édition de liens par g++ quant à leur méthode what() et à leur destructeur, quand je n'utilise pas le mot clé throw.
Dans le prototype de la fonction, tu veux dire ?
Oui.
C'est normal : le "throw()" fait partie du prototype de la fonction. Si tu déclares une fonction membre what() avec un autre prototype, ça cache la fonction std::exception::what() au lieu de la remplacer.
Je croyais que le mot clé throw servait à déclarer quelles exceptions la méthode concernée était susceptible de lever,
C'est bien ça.
je constate qu'il n'en est rien,
Ben si. Le "throw()" indique que what() ne lance jamais d'exception.
Dans ces conditions, c'est à mon avis dommage que le compilateur accepte un code comme celui-ci:
struct foo {
void bar() throw () { int *p = new int; delete p; }
};
Ou peut-être existe-t-il un intérêt à la chose que je n'ai pas saisi ?
-- BBP
Fabien LE LEZ
On Wed, 04 Jan 2006 11:31:35 +0100, Brieuc Jeunhomme :
Ben si. Le "throw()" indique que what() ne lance jamais d'exception.
Dans ces conditions, c'est à mon avis dommage que le compilateur accepte un code comme celui-ci:
Le code suivant est également accepté, et parfaitement légal :
void f() throw() { throw "Exception"; }
On peut lancer une exception à l'intérieur d'une fonction "nothrow". La spécification "throw()" ne sert qu'à assurer qu'on ne sortira pas de la fonction par une exception.
En fait, lancer une exception dans une telle fonction appelle terminate(), i.e. le programme s'arrête immédiatement ; aucun destructeur n'est appelé.
On Wed, 04 Jan 2006 11:31:35 +0100, Brieuc Jeunhomme
<brieuc.jeunhomme@gmail.com>:
Ben si. Le "throw()" indique que what() ne lance jamais d'exception.
Dans ces conditions, c'est à mon avis dommage que le compilateur accepte
un code comme celui-ci:
Le code suivant est également accepté, et parfaitement légal :
void f() throw()
{
throw "Exception";
}
On peut lancer une exception à l'intérieur d'une fonction "nothrow".
La spécification "throw()" ne sert qu'à assurer qu'on ne sortira pas
de la fonction par une exception.
En fait, lancer une exception dans une telle fonction appelle
terminate(), i.e. le programme s'arrête immédiatement ; aucun
destructeur n'est appelé.
On Wed, 04 Jan 2006 11:31:35 +0100, Brieuc Jeunhomme :
Ben si. Le "throw()" indique que what() ne lance jamais d'exception.
Dans ces conditions, c'est à mon avis dommage que le compilateur accepte un code comme celui-ci:
Le code suivant est également accepté, et parfaitement légal :
void f() throw() { throw "Exception"; }
On peut lancer une exception à l'intérieur d'une fonction "nothrow". La spécification "throw()" ne sert qu'à assurer qu'on ne sortira pas de la fonction par une exception.
En fait, lancer une exception dans une telle fonction appelle terminate(), i.e. le programme s'arrête immédiatement ; aucun destructeur n'est appelé.
kanze
Brieuc Jeunhomme wrote:
[...]
Ben si. Le "throw()" indique que what() ne lance jamais d'exception.
Dans ces conditions, c'est à mon avis dommage que le compilateur accepte un code comme celui-ci:
struct foo {
void bar() throw () { int *p = new int; delete p; }
};
Ou peut-être existe-t-il un intérêt à la chose que je n'ai pas saisi ?
AMHA, aucun, mais l'argument se base un peu sur l'idée qu'en C++, le compilateur n'enforce un contrat que s'il peut le faire 100% du temps. Donc, par exemple, où est l'intérêt de pouvoir écrire :
int& f() { int i = 3 ; return i ; }
Dans le cas de bar, ci-dessus, supposons qu'elle soit conçue pour ne servir que dans une application où on a remplacé le new_handler avec un qui abort. Dans ce cas-là, bar() ne peut pas lever une exception, mais comment le compilateur peut-il le savoir ?
Le throw() se comporte exactement comme une vérification de post-condition. Personellement, j'aurais préféré plus une vérification statique, quitte à ce que le programmeur soit obligé à insérer du code supplémentaire, du genre :
Ici, moi, en tant que programmeur, sait que le bloc de try est supérflu, mais comment veux-tu que le compilateur le sache ?
Mais c'est un avis personnel, qui n'engage que moi. Et la solution adoptée n'est pas vraiment mauvaise non plus.
-- James Kanze GABI Software 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
Brieuc Jeunhomme wrote:
[...]
Ben si. Le "throw()" indique que what() ne lance jamais d'exception.
Dans ces conditions, c'est à mon avis dommage que le
compilateur accepte un code comme celui-ci:
struct foo {
void bar() throw () {
int *p = new int;
delete p;
}
};
Ou peut-être existe-t-il un intérêt à la chose que je n'ai pas
saisi ?
AMHA, aucun, mais l'argument se base un peu sur l'idée qu'en
C++, le compilateur n'enforce un contrat que s'il peut le faire
100% du temps. Donc, par exemple, où est l'intérêt de pouvoir
écrire :
int& f() { int i = 3 ; return i ; }
Dans le cas de bar, ci-dessus, supposons qu'elle soit conçue
pour ne servir que dans une application où on a remplacé le
new_handler avec un qui abort. Dans ce cas-là, bar() ne peut pas
lever une exception, mais comment le compilateur peut-il le
savoir ?
Le throw() se comporte exactement comme une vérification de
post-condition. Personellement, j'aurais préféré plus une
vérification statique, quitte à ce que le programmeur soit
obligé à insérer du code supplémentaire, du genre :
Ben si. Le "throw()" indique que what() ne lance jamais d'exception.
Dans ces conditions, c'est à mon avis dommage que le compilateur accepte un code comme celui-ci:
struct foo {
void bar() throw () { int *p = new int; delete p; }
};
Ou peut-être existe-t-il un intérêt à la chose que je n'ai pas saisi ?
AMHA, aucun, mais l'argument se base un peu sur l'idée qu'en C++, le compilateur n'enforce un contrat que s'il peut le faire 100% du temps. Donc, par exemple, où est l'intérêt de pouvoir écrire :
int& f() { int i = 3 ; return i ; }
Dans le cas de bar, ci-dessus, supposons qu'elle soit conçue pour ne servir que dans une application où on a remplacé le new_handler avec un qui abort. Dans ce cas-là, bar() ne peut pas lever une exception, mais comment le compilateur peut-il le savoir ?
Le throw() se comporte exactement comme une vérification de post-condition. Personellement, j'aurais préféré plus une vérification statique, quitte à ce que le programmeur soit obligé à insérer du code supplémentaire, du genre :
Ici, moi, en tant que programmeur, sait que le bloc de try est supérflu, mais comment veux-tu que le compilateur le sache ?
Mais c'est un avis personnel, qui n'engage que moi. Et la solution adoptée n'est pas vraiment mauvaise non plus.
-- James Kanze GABI Software 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
Brieuc Jeunhomme
AMHA, aucun, mais l'argument se base un peu sur l'idée qu'en C++, le compilateur n'enforce un contrat que s'il peut le faire 100% du temps.
Je comprends. Cependant, quand le programmeur a fermement décidé de se tirer dans le pied, il est de toute façon quasiment impossible de l'en empêcher sans rendre le langage inutilisable.
Pour la route, un petit exemple qui crashe sans cast explicite, hop sans les mains:
static const int k = 0;
void foo( const int * p ) { union { const int * cst; int * pas_cst; } ptr;
ptr.cst = p; * ptr.pas_cst = 42; }
int main() { foo( & k ); return 0; }
Dans le cas de bar, ci-dessus, supposons qu'elle soit conçue pour ne servir que dans une application où on a remplacé le new_handler avec un qui abort. Dans ce cas-là, bar() ne peut pas lever une exception, mais comment le compilateur peut-il le savoir ?
Effectivement. Dommage que ce ne soit pas déclarable d'une manière ou d'une autre.
Le throw() se comporte exactement comme une vérification de post-condition. Personellement, j'aurais préféré plus une vérification statique
Tout à fait d'accord.
Ici, moi, en tant que programmeur, sait que le bloc de try est supérflu, mais comment veux-tu que le compilateur le sache ?
g++ --I_KNOW_WHAT_I_AM_DOING :=)
Sérieusement, c'est dommage de ne pas avoir moyen de déclarer autour d'un bloc de code que non, il ne lèvera pas telle exception.
Mais c'est un avis personnel, qui n'engage que moi. Et la solution adoptée n'est pas vraiment mauvaise non plus.
J'ai beaucoup de mal à comprendre ce qu'elle apporte, puisque le résultat, in fine, c'est qu'il ne suffit pas de lire le prototype pour savoir quelles exceptions on risque de se prendre sur la tête en appelant la fonction, alors que ça semblait justement être le but (aha tout à fait louable) à la base.
-- BBP
AMHA, aucun, mais l'argument se base un peu sur l'idée qu'en
C++, le compilateur n'enforce un contrat que s'il peut le faire
100% du temps.
Je comprends. Cependant, quand le programmeur a fermement décidé de se
tirer dans le pied, il est de toute façon quasiment impossible de l'en
empêcher sans rendre le langage inutilisable.
Pour la route, un petit exemple qui crashe sans cast explicite, hop sans
les mains:
static const int k = 0;
void foo( const int * p ) {
union { const int * cst; int * pas_cst; } ptr;
ptr.cst = p;
* ptr.pas_cst = 42;
}
int main() {
foo( & k );
return 0;
}
Dans le cas de bar, ci-dessus, supposons qu'elle soit conçue
pour ne servir que dans une application où on a remplacé le
new_handler avec un qui abort. Dans ce cas-là, bar() ne peut pas
lever une exception, mais comment le compilateur peut-il le
savoir ?
Effectivement. Dommage que ce ne soit pas déclarable d'une manière ou
d'une autre.
Le throw() se comporte exactement comme une vérification de
post-condition. Personellement, j'aurais préféré plus une
vérification statique
Tout à fait d'accord.
Ici, moi, en tant que programmeur, sait que le bloc de try est
supérflu, mais comment veux-tu que le compilateur le sache ?
g++ --I_KNOW_WHAT_I_AM_DOING :=)
Sérieusement, c'est dommage de ne pas avoir moyen de déclarer autour
d'un bloc de code que non, il ne lèvera pas telle exception.
Mais c'est un avis personnel, qui n'engage que moi. Et la
solution adoptée n'est pas vraiment mauvaise non plus.
J'ai beaucoup de mal à comprendre ce qu'elle apporte, puisque le
résultat, in fine, c'est qu'il ne suffit pas de lire le prototype pour
savoir quelles exceptions on risque de se prendre sur la tête en
appelant la fonction, alors que ça semblait justement être le but (aha
tout à fait louable) à la base.
AMHA, aucun, mais l'argument se base un peu sur l'idée qu'en C++, le compilateur n'enforce un contrat que s'il peut le faire 100% du temps.
Je comprends. Cependant, quand le programmeur a fermement décidé de se tirer dans le pied, il est de toute façon quasiment impossible de l'en empêcher sans rendre le langage inutilisable.
Pour la route, un petit exemple qui crashe sans cast explicite, hop sans les mains:
static const int k = 0;
void foo( const int * p ) { union { const int * cst; int * pas_cst; } ptr;
ptr.cst = p; * ptr.pas_cst = 42; }
int main() { foo( & k ); return 0; }
Dans le cas de bar, ci-dessus, supposons qu'elle soit conçue pour ne servir que dans une application où on a remplacé le new_handler avec un qui abort. Dans ce cas-là, bar() ne peut pas lever une exception, mais comment le compilateur peut-il le savoir ?
Effectivement. Dommage que ce ne soit pas déclarable d'une manière ou d'une autre.
Le throw() se comporte exactement comme une vérification de post-condition. Personellement, j'aurais préféré plus une vérification statique
Tout à fait d'accord.
Ici, moi, en tant que programmeur, sait que le bloc de try est supérflu, mais comment veux-tu que le compilateur le sache ?
g++ --I_KNOW_WHAT_I_AM_DOING :=)
Sérieusement, c'est dommage de ne pas avoir moyen de déclarer autour d'un bloc de code que non, il ne lèvera pas telle exception.
Mais c'est un avis personnel, qui n'engage que moi. Et la solution adoptée n'est pas vraiment mauvaise non plus.
J'ai beaucoup de mal à comprendre ce qu'elle apporte, puisque le résultat, in fine, c'est qu'il ne suffit pas de lire le prototype pour savoir quelles exceptions on risque de se prendre sur la tête en appelant la fonction, alors que ça semblait justement être le but (aha tout à fait louable) à la base.
-- BBP
Fabien LE LEZ
On Thu, 05 Jan 2006 13:26:25 +0100, Brieuc Jeunhomme :
J'ai beaucoup de mal à comprendre ce qu'elle apporte
Moi aussi ;-)
En fait, j'ai finalement décidé de remplacer
void f() throw (Machin);
par
void f(); // throw (Machin)
On Thu, 05 Jan 2006 13:26:25 +0100, Brieuc Jeunhomme
<brieuc.jeunhomme@gmail.com>:
J'ai beaucoup de mal à comprendre ce qu'elle apporte
On Thu, 05 Jan 2006 13:26:25 +0100, Brieuc Jeunhomme :
J'ai beaucoup de mal à comprendre ce qu'elle apporte
Moi aussi ;-)
En fait, j'ai finalement décidé de remplacer
void f() throw (Machin);
par
void f(); // throw (Machin)
kanze
Brieuc Jeunhomme wrote:
AMHA, aucun, mais l'argument se base un peu sur l'idée qu'en C++, le compilateur n'enforce un contrat que s'il peut le faire 100% du temps.
Je comprends. Cependant, quand le programmeur a fermement décidé de se tirer dans le pied, il est de toute façon quasiment impossible de l'en empêcher sans rendre le langage inutilisable.
C'est pourquoi il y a tellement de comportement indéfini dans le C++.
[...]
Sérieusement, c'est dommage de ne pas avoir moyen de déclarer autour d'un bloc de code que non, il ne lèvera pas telle exception.
Si le code est une fonction, on l'a. Mais c'est une promesse du programmeur, qui n'est pas vérifiée au moment de la compilation. En revanche, à la différence de prèsque tous les cas semblables en C++, dans ce cas-ci, il y a une vérification lors de l'exécution.
Mais c'est un avis personnel, qui n'engage que moi. Et la solution adoptée n'est pas vraiment mauvaise non plus.
J'ai beaucoup de mal à comprendre ce qu'elle apporte, puisque le résultat, in fine, c'est qu'il ne suffit pas de lire le prototype pour savoir quelles exceptions on risque de se prendre sur la tête en appelant la fonction, alors que ça semblait justement être le but (aha tout à fait louable) à la base.
Comment ça ? Le prototype indique bien les exceptions possibles, au moins s'il est bien écrit.
Dans la pratique, on constate qu'il y a peu d'intérêt à y aller en détail. Il est très important de savoir si la fonction peut lever une exception ou non. Une fois qu'on sait qu'elle peut lever une exception, le ou les types en est rélativement sans intérêt. On écrit donc :
void f( int ) throw() ; // Ne peut pas lever une exception void g( int ) ; // Peut lever une exception
Et comme j'ai déjà indiqué, le compilateur génère automatiquement la vérification de cette post-condition de f().
-- James Kanze GABI Software 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
Brieuc Jeunhomme wrote:
AMHA, aucun, mais l'argument se base un peu sur l'idée qu'en
C++, le compilateur n'enforce un contrat que s'il peut le
faire 100% du temps.
Je comprends. Cependant, quand le programmeur a fermement
décidé de se tirer dans le pied, il est de toute façon
quasiment impossible de l'en empêcher sans rendre le langage
inutilisable.
C'est pourquoi il y a tellement de comportement indéfini dans le
C++.
[...]
Sérieusement, c'est dommage de ne pas avoir moyen de déclarer
autour d'un bloc de code que non, il ne lèvera pas telle
exception.
Si le code est une fonction, on l'a. Mais c'est une promesse du
programmeur, qui n'est pas vérifiée au moment de la compilation.
En revanche, à la différence de prèsque tous les cas semblables
en C++, dans ce cas-ci, il y a une vérification lors de
l'exécution.
Mais c'est un avis personnel, qui n'engage que moi. Et la
solution adoptée n'est pas vraiment mauvaise non plus.
J'ai beaucoup de mal à comprendre ce qu'elle apporte, puisque
le résultat, in fine, c'est qu'il ne suffit pas de lire le
prototype pour savoir quelles exceptions on risque de se
prendre sur la tête en appelant la fonction, alors que ça
semblait justement être le but (aha tout à fait louable) à la
base.
Comment ça ? Le prototype indique bien les exceptions possibles,
au moins s'il est bien écrit.
Dans la pratique, on constate qu'il y a peu d'intérêt à y aller
en détail. Il est très important de savoir si la fonction peut
lever une exception ou non. Une fois qu'on sait qu'elle peut
lever une exception, le ou les types en est rélativement sans
intérêt. On écrit donc :
void f( int ) throw() ; // Ne peut pas lever une exception
void g( int ) ; // Peut lever une exception
Et comme j'ai déjà indiqué, le compilateur génère
automatiquement la vérification de cette post-condition de f().
--
James Kanze GABI Software
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
AMHA, aucun, mais l'argument se base un peu sur l'idée qu'en C++, le compilateur n'enforce un contrat que s'il peut le faire 100% du temps.
Je comprends. Cependant, quand le programmeur a fermement décidé de se tirer dans le pied, il est de toute façon quasiment impossible de l'en empêcher sans rendre le langage inutilisable.
C'est pourquoi il y a tellement de comportement indéfini dans le C++.
[...]
Sérieusement, c'est dommage de ne pas avoir moyen de déclarer autour d'un bloc de code que non, il ne lèvera pas telle exception.
Si le code est une fonction, on l'a. Mais c'est une promesse du programmeur, qui n'est pas vérifiée au moment de la compilation. En revanche, à la différence de prèsque tous les cas semblables en C++, dans ce cas-ci, il y a une vérification lors de l'exécution.
Mais c'est un avis personnel, qui n'engage que moi. Et la solution adoptée n'est pas vraiment mauvaise non plus.
J'ai beaucoup de mal à comprendre ce qu'elle apporte, puisque le résultat, in fine, c'est qu'il ne suffit pas de lire le prototype pour savoir quelles exceptions on risque de se prendre sur la tête en appelant la fonction, alors que ça semblait justement être le but (aha tout à fait louable) à la base.
Comment ça ? Le prototype indique bien les exceptions possibles, au moins s'il est bien écrit.
Dans la pratique, on constate qu'il y a peu d'intérêt à y aller en détail. Il est très important de savoir si la fonction peut lever une exception ou non. Une fois qu'on sait qu'elle peut lever une exception, le ou les types en est rélativement sans intérêt. On écrit donc :
void f( int ) throw() ; // Ne peut pas lever une exception void g( int ) ; // Peut lever une exception
Et comme j'ai déjà indiqué, le compilateur génère automatiquement la vérification de cette post-condition de f().
-- James Kanze GABI Software 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
Fabien LE LEZ wrote:
On Thu, 05 Jan 2006 13:26:25 +0100, Brieuc Jeunhomme :
J'ai beaucoup de mal à comprendre ce qu'elle apporte
Moi aussi ;-)
Elle apporte que le compilateur génère automatiquement la vérification du contrat.
En fait, j'ai finalement décidé de remplacer
void f() throw (Machin);
par
void f(); // throw (Machin)
Est-ce que le fait que f() peut ne lever que Machin fasse partie du contrat de la fonction ? Si oui, dans le deuxième cas, tu es bien obligé à écrire du code supplémentaire quelque part pour vérifier que le contrat est maintenu. Dans le premier, c'est le compilateur qui le fait pour toi.
Ceci dit, je vois mal l'intérêt d'un tel contrat. Jusqu'ici, le seul contrat que j'ai trouvé utile dans la pratique, c'est « throw() ».
-- James Kanze GABI Software 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
Fabien LE LEZ wrote:
On Thu, 05 Jan 2006 13:26:25 +0100, Brieuc Jeunhomme
<brieuc.jeunhomme@gmail.com>:
J'ai beaucoup de mal à comprendre ce qu'elle apporte
Moi aussi ;-)
Elle apporte que le compilateur génère automatiquement la
vérification du contrat.
En fait, j'ai finalement décidé de remplacer
void f() throw (Machin);
par
void f(); // throw (Machin)
Est-ce que le fait que f() peut ne lever que Machin fasse partie
du contrat de la fonction ? Si oui, dans le deuxième cas, tu es
bien obligé à écrire du code supplémentaire quelque part pour
vérifier que le contrat est maintenu. Dans le premier, c'est le
compilateur qui le fait pour toi.
Ceci dit, je vois mal l'intérêt d'un tel contrat. Jusqu'ici, le
seul contrat que j'ai trouvé utile dans la pratique, c'est
« throw() ».
--
James Kanze GABI Software
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 Thu, 05 Jan 2006 13:26:25 +0100, Brieuc Jeunhomme :
J'ai beaucoup de mal à comprendre ce qu'elle apporte
Moi aussi ;-)
Elle apporte que le compilateur génère automatiquement la vérification du contrat.
En fait, j'ai finalement décidé de remplacer
void f() throw (Machin);
par
void f(); // throw (Machin)
Est-ce que le fait que f() peut ne lever que Machin fasse partie du contrat de la fonction ? Si oui, dans le deuxième cas, tu es bien obligé à écrire du code supplémentaire quelque part pour vérifier que le contrat est maintenu. Dans le premier, c'est le compilateur qui le fait pour toi.
Ceci dit, je vois mal l'intérêt d'un tel contrat. Jusqu'ici, le seul contrat que j'ai trouvé utile dans la pratique, c'est « throw() ».
-- James Kanze GABI Software 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
Fabien LE LEZ
On 6 Jan 2006 00:55:34 -0800, "kanze" :
void f() throw (Machin);
par
void f(); // throw (Machin)
Est-ce que le fait que f() peut ne lever que Machin fasse partie du contrat de la fonction ?
Non. C'est plus de l'ordre de la documentation.
Ceci dit, je vois mal l'intérêt d'un tel contrat. Jusqu'ici, le seul contrat que j'ai trouvé utile dans la pratique, c'est « throw() ».
Idem.
En découvrant les spécifications d'exceptions, j'avais mis quelques spécifications non vides, puis je me suis aperçu a posteriori que ce n'était pas forcément une bonne chose.
À noter, les versions récentes de VC++ ignorent les spécifications non vides.
On 6 Jan 2006 00:55:34 -0800, "kanze" <kanze@gabi-soft.fr>:
void f() throw (Machin);
par
void f(); // throw (Machin)
Est-ce que le fait que f() peut ne lever que Machin fasse partie
du contrat de la fonction ?
Non. C'est plus de l'ordre de la documentation.
Ceci dit, je vois mal l'intérêt d'un tel contrat. Jusqu'ici, le
seul contrat que j'ai trouvé utile dans la pratique, c'est
« throw() ».
Idem.
En découvrant les spécifications d'exceptions, j'avais mis quelques
spécifications non vides, puis je me suis aperçu a posteriori que ce
n'était pas forcément une bonne chose.
À noter, les versions récentes de VC++ ignorent les spécifications non
vides.
Est-ce que le fait que f() peut ne lever que Machin fasse partie du contrat de la fonction ?
Non. C'est plus de l'ordre de la documentation.
Ceci dit, je vois mal l'intérêt d'un tel contrat. Jusqu'ici, le seul contrat que j'ai trouvé utile dans la pratique, c'est « throw() ».
Idem.
En découvrant les spécifications d'exceptions, j'avais mis quelques spécifications non vides, puis je me suis aperçu a posteriori que ce n'était pas forcément une bonne chose.
À noter, les versions récentes de VC++ ignorent les spécifications non vides.
kanze
Fabien LE LEZ wrote:
On 6 Jan 2006 00:55:34 -0800, "kanze" :
void f() throw (Machin);
par
void f(); // throw (Machin)
Est-ce que le fait que f() peut ne lever que Machin fasse partie du contrat de la fonction ?
Non. C'est plus de l'ordre de la documentation.
Non, c'est plus que de la documentation, parce que c'est enforcé par le code généré par le compilateur. C'est donc du code que tu n'as pas à écrire.
Ceci dit, je vois mal l'intérêt d'un tel contrat. Jusqu'ici, le seul contrat que j'ai trouvé utile dans la pratique, c'est « throw() ».
Idem.
Idem, en effet. C'est une partie du contrat enforcée par le compilateur.
En découvrant les spécifications d'exceptions, j'avais mis quelques spécifications non vides, puis je me suis aperçu a posteriori que ce n'était pas forcément une bonne chose.
Je crois que le problème, c'est un de point de vue. Et je crois qu'il a été général pendant très longtemps, ce qui a donné une mauvaise réputation aux spécifications d'exceptions. Il y a (ou avait, au moins) une tendance à vouloir les utiliser pour spécifier les exceptions que peut lever une fonction ; les types d'erreurs, donc, auxquels l'utilisateur doit s'attendre.
En fait, si on considère les choses de près, on constate que :
-- la véritable garantie, c'est l'inverse -- les exceptions qu'on ne peut pas avoir, et donc, dont on n'a pas à s'occuper ; et
-- la garantie de loin la plus intéressante, c'est la garantie que la fonction ne lève aucune exception, du tout.
À noter, les versions récentes de VC++ ignorent les spécifications non vides.
Ce qui fait qu'elles ne sont pas des compilateurs C++. Mais c'est moins un problème que le fait qu'elles ignorent aussi export -- je ne vois pas beaucoup d'utilité des spécifications non-vide, tandis que j'ai réelement besoin d'export.
-- James Kanze GABI Software 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
Fabien LE LEZ wrote:
On 6 Jan 2006 00:55:34 -0800, "kanze" <kanze@gabi-soft.fr>:
void f() throw (Machin);
par
void f(); // throw (Machin)
Est-ce que le fait que f() peut ne lever que Machin fasse partie du
contrat de la fonction ?
Non. C'est plus de l'ordre de la documentation.
Non, c'est plus que de la documentation, parce que c'est enforcé
par le code généré par le compilateur. C'est donc du code que tu
n'as pas à écrire.
Ceci dit, je vois mal l'intérêt d'un tel contrat. Jusqu'ici,
le seul contrat que j'ai trouvé utile dans la pratique, c'est
« throw() ».
Idem.
Idem, en effet. C'est une partie du contrat enforcée par le
compilateur.
En découvrant les spécifications d'exceptions, j'avais mis
quelques spécifications non vides, puis je me suis aperçu a
posteriori que ce n'était pas forcément une bonne chose.
Je crois que le problème, c'est un de point de vue. Et je crois
qu'il a été général pendant très longtemps, ce qui a donné une
mauvaise réputation aux spécifications d'exceptions. Il y a (ou
avait, au moins) une tendance à vouloir les utiliser pour
spécifier les exceptions que peut lever une fonction ; les
types d'erreurs, donc, auxquels l'utilisateur doit s'attendre.
En fait, si on considère les choses de près, on constate que :
-- la véritable garantie, c'est l'inverse -- les exceptions
qu'on ne peut pas avoir, et donc, dont on n'a pas à
s'occuper ; et
-- la garantie de loin la plus intéressante, c'est la garantie
que la fonction ne lève aucune exception, du tout.
À noter, les versions récentes de VC++ ignorent les
spécifications non vides.
Ce qui fait qu'elles ne sont pas des compilateurs C++. Mais
c'est moins un problème que le fait qu'elles ignorent aussi
export -- je ne vois pas beaucoup d'utilité des spécifications
non-vide, tandis que j'ai réelement besoin d'export.
--
James Kanze GABI Software
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
Est-ce que le fait que f() peut ne lever que Machin fasse partie du contrat de la fonction ?
Non. C'est plus de l'ordre de la documentation.
Non, c'est plus que de la documentation, parce que c'est enforcé par le code généré par le compilateur. C'est donc du code que tu n'as pas à écrire.
Ceci dit, je vois mal l'intérêt d'un tel contrat. Jusqu'ici, le seul contrat que j'ai trouvé utile dans la pratique, c'est « throw() ».
Idem.
Idem, en effet. C'est une partie du contrat enforcée par le compilateur.
En découvrant les spécifications d'exceptions, j'avais mis quelques spécifications non vides, puis je me suis aperçu a posteriori que ce n'était pas forcément une bonne chose.
Je crois que le problème, c'est un de point de vue. Et je crois qu'il a été général pendant très longtemps, ce qui a donné une mauvaise réputation aux spécifications d'exceptions. Il y a (ou avait, au moins) une tendance à vouloir les utiliser pour spécifier les exceptions que peut lever une fonction ; les types d'erreurs, donc, auxquels l'utilisateur doit s'attendre.
En fait, si on considère les choses de près, on constate que :
-- la véritable garantie, c'est l'inverse -- les exceptions qu'on ne peut pas avoir, et donc, dont on n'a pas à s'occuper ; et
-- la garantie de loin la plus intéressante, c'est la garantie que la fonction ne lève aucune exception, du tout.
À noter, les versions récentes de VC++ ignorent les spécifications non vides.
Ce qui fait qu'elles ne sont pas des compilateurs C++. Mais c'est moins un problème que le fait qu'elles ignorent aussi export -- je ne vois pas beaucoup d'utilité des spécifications non-vide, tandis que j'ai réelement besoin d'export.
-- James Kanze GABI Software 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