kanze wrote on 25/07/2006 09:47:En C++ (§15.4/8,9) :
Pas de distinction entre deux catégories d'exception. Et s'il y
a une exception-specification, c'est véritablement une
garantie : quoi qui arrive, on ne sort pas avec une exception
qui n'est pas citée, et si elle est vide, on ne sort pas de la
fonction avec une exception.
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
kanze wrote on 25/07/2006 09:47:
En C++ (§15.4/8,9) :
Pas de distinction entre deux catégories d'exception. Et s'il y
a une exception-specification, c'est véritablement une
garantie : quoi qui arrive, on ne sort pas avec une exception
qui n'est pas citée, et si elle est vide, on ne sort pas de la
fonction avec une exception.
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
kanze wrote on 25/07/2006 09:47:En C++ (§15.4/8,9) :
Pas de distinction entre deux catégories d'exception. Et s'il y
a une exception-specification, c'est véritablement une
garantie : quoi qui arrive, on ne sort pas avec une exception
qui n'est pas citée, et si elle est vide, on ne sort pas de la
fonction avec une exception.
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
kanze wrote on 25/07/2006 09:47:Je parlais de ce qu'on appelle les « out parameters » en
anglais.
ok donc des "paramètres par référence", à moins que tu
n'inclues implicitement également le mot-clé "out" jouant sur
les régles de modifications du paramètre formel (ou pire les
modifiers de .net).
Java ne supporte ni out, ni inout.
il supporte 'final' qui agit comme 'const' pour un "in
parameter".
(Le C++, en fait, ne supporte pas réelement out non plus.
Mais on arrive aux mêmes fins avec des inout la plupart du
temps.)
match nul avec une référence Java - sauf pour changer la
valeur d'un pointeur (un "out type [const] * &").C'est un concepte assez connu, il me semble.
archi connu ! mais comme je n'ai vu aucun lien avec le point
discuté...
À titre d'exemple, essayer d'écrire l'équivalant en Java de
std::swap.
swaper quoi appartenant à qui ??
si c'est une classe clonable je ne vois pas le problème, si
c'est des types primitifs c'est également facile, si par
contre ce sont des pointeurs ... je l'ai déjà dit.
ceci étant, les map et autres ensembles triés existent (c'est
là que le "appartenant à qui" intervient), il sera donc
toujours possible de swap dans un contexte donné.
Je n'arrive pas à comprendre ce que tu ne comprends pas. Tu
sais très bien que le Java ne t'oblige à lister que
certaines exceptions, non toutes. C'est là le problème,
parce que la garantie la plus intéressante, c'est bien qu'il
n'y aura pas d'exception. Du tout. Qu'elle hérite de
RuntimeException ou de Error, ou non. C'est dans la pratique
peut-être la seule garantie un peu près utile.
je suis désolé mais justement la classe de l'exception à son
importance (tel que Java se pratique en tout cas). les erreurs
RuntimeException et Error sont réputés non récupérables - un
peu moins pour les filles de RuntimeException, mais la plupart
résulterait d'erreur ou de manque grossier dans le codage
(aucune méthode standard ne lève de telle exception par
surprise).
Idéalement, on l'aurait, et elle serait vérifiée par le
compilateur. En C++, on l'a, mais avec vérification lors de
l'exécution -- c'est loin d'être idéal, mais c'est mieux que
rien.
tu peux m'expliquer ce point ?
le code:
class Exception {
public:
Exception(int) {}
};
int foo() throw()
{
int x = 3, y = 0;
int z = x / y;
int* p = NULL;
*p = 1;
throw Exception(3);
}
a, il me semble, 3 raisons de partir en exception; si je
catche l'appel à foo par un handler générique ("...") je tombe
pour chacune d'elle (en commentant la précédante) dans mon
handler.
que signifie alors la "vérification à l'exécution" ?
il faut que je change de compilo ?
C'est à croire que tu connais ni le Java, ni le C++, parce
que tu l'a exactement à l'envers. La déclaration ci-dessus
en Java garantie seulement que la fonction ne peut pas lever
une parmi un petit sous-ensemble des exceptions. Et j'ai
déjà (souvent d'ailleurs) vu des fonctions Java avec une
déclaration pareille sortir par une exception.
une exception que tu n'as pas à déclarer car dans 99% des cas
cela ne sert à rien (VM morte, stack corrompu, etc ...) - dit
que cet indéterminisme te parait inacceptable (le cas échéant)
mais pas que ce n'est pas une garantie (ou accepte que
"garantie" ait un sens propre au langage).
Quand tu spécifies throw() sur une fonction en C++, en
revanche, tu es 100% sûr que la fonction ne sortira jamais
par une exception.
ben j'attends ta réponse sur l'exemple précédent, parce que
l'expérience me montre le contraire pour l'instant.
La seule différence entre les deux, c'est qu'il faut en
citer les unes dans la déclaration de la fonction, mais pas
les autres. C'est vraiement la seule différence, selon le
langage. Et si tu régardes les cas réels, dans la API de
Java, tu constateras que les seules qu'il faut lister, ce
sont celles qu'il faut typiquement traiter à un niveau tout
près. C-à-d celles où on se servira d'un code de rétour
d'une fonction en C++, parce que c'est quand même moins
lourd.
je suis assez d'accord; mais la lourdeur ne sera présente que
si on fait exprès d'être lourd: on peut (et il est pertinent
de) faire un test avant l'opération et sortir directement en
erreur ou on peut y aller bourrin et jouer du try/catch, e.g.
int foo(Object definedOrNot){
if (definedOrNot == null)
return -1;
return definedOrNot.g();
}
ou
int foo(Object definedOrNot){
try {
return definedOrNot.g();
}
catch (NullPointerException npe){
return -1;
}
}
les 2 sont valides, la seconde est inutilement lourde; reste
que la 'proximité' utilisée ici n'est pas toujours vérifiée;
le codeur doit faire preuve de discernement.
L'exemple typique où une exception est la solution préférée,
c'est std::bad_alloc (en C++) ou java.lang.OutOfMemoryError
(en Java). C'est un cas type où l'erreur ne pourrait pas
être traitée localement.
"le codeur doit faire preuve de discernement" ...
s'il s'agit d'une initialisation de buffer de transaction, je
ferais un traitement local pour essayer de poursuivre avec un
tampon plus petit plutôt que de jeter l'éponge.
Il y en a beaucoup de ce genre qui dérivent de
RuntimeException ; ce sont des erreurs que, si on veut les
traiter, il faut les traiter à un niveau assez élevé,
je dirais plutôt cela des Error.
En C++ (§15.4/8,9) :
Pas de distinction entre deux catégories d'exception. Et
s'il y a une exception-specification, c'est véritablement
une garantie : quoi qui arrive, on ne sort pas avec une
exception qui n'est pas citée, et si elle est vide, on ne
sort pas de la fonction avec une exception.
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
kanze wrote on 25/07/2006 09:47:
Je parlais de ce qu'on appelle les « out parameters » en
anglais.
ok donc des "paramètres par référence", à moins que tu
n'inclues implicitement également le mot-clé "out" jouant sur
les régles de modifications du paramètre formel (ou pire les
modifiers de .net).
Java ne supporte ni out, ni inout.
il supporte 'final' qui agit comme 'const' pour un "in
parameter".
(Le C++, en fait, ne supporte pas réelement out non plus.
Mais on arrive aux mêmes fins avec des inout la plupart du
temps.)
match nul avec une référence Java - sauf pour changer la
valeur d'un pointeur (un "out type [const] * &").
C'est un concepte assez connu, il me semble.
archi connu ! mais comme je n'ai vu aucun lien avec le point
discuté...
À titre d'exemple, essayer d'écrire l'équivalant en Java de
std::swap.
swaper quoi appartenant à qui ??
si c'est une classe clonable je ne vois pas le problème, si
c'est des types primitifs c'est également facile, si par
contre ce sont des pointeurs ... je l'ai déjà dit.
ceci étant, les map et autres ensembles triés existent (c'est
là que le "appartenant à qui" intervient), il sera donc
toujours possible de swap dans un contexte donné.
Je n'arrive pas à comprendre ce que tu ne comprends pas. Tu
sais très bien que le Java ne t'oblige à lister que
certaines exceptions, non toutes. C'est là le problème,
parce que la garantie la plus intéressante, c'est bien qu'il
n'y aura pas d'exception. Du tout. Qu'elle hérite de
RuntimeException ou de Error, ou non. C'est dans la pratique
peut-être la seule garantie un peu près utile.
je suis désolé mais justement la classe de l'exception à son
importance (tel que Java se pratique en tout cas). les erreurs
RuntimeException et Error sont réputés non récupérables - un
peu moins pour les filles de RuntimeException, mais la plupart
résulterait d'erreur ou de manque grossier dans le codage
(aucune méthode standard ne lève de telle exception par
surprise).
Idéalement, on l'aurait, et elle serait vérifiée par le
compilateur. En C++, on l'a, mais avec vérification lors de
l'exécution -- c'est loin d'être idéal, mais c'est mieux que
rien.
tu peux m'expliquer ce point ?
le code:
class Exception {
public:
Exception(int) {}
};
int foo() throw()
{
int x = 3, y = 0;
int z = x / y;
int* p = NULL;
*p = 1;
throw Exception(3);
}
a, il me semble, 3 raisons de partir en exception; si je
catche l'appel à foo par un handler générique ("...") je tombe
pour chacune d'elle (en commentant la précédante) dans mon
handler.
que signifie alors la "vérification à l'exécution" ?
il faut que je change de compilo ?
C'est à croire que tu connais ni le Java, ni le C++, parce
que tu l'a exactement à l'envers. La déclaration ci-dessus
en Java garantie seulement que la fonction ne peut pas lever
une parmi un petit sous-ensemble des exceptions. Et j'ai
déjà (souvent d'ailleurs) vu des fonctions Java avec une
déclaration pareille sortir par une exception.
une exception que tu n'as pas à déclarer car dans 99% des cas
cela ne sert à rien (VM morte, stack corrompu, etc ...) - dit
que cet indéterminisme te parait inacceptable (le cas échéant)
mais pas que ce n'est pas une garantie (ou accepte que
"garantie" ait un sens propre au langage).
Quand tu spécifies throw() sur une fonction en C++, en
revanche, tu es 100% sûr que la fonction ne sortira jamais
par une exception.
ben j'attends ta réponse sur l'exemple précédent, parce que
l'expérience me montre le contraire pour l'instant.
La seule différence entre les deux, c'est qu'il faut en
citer les unes dans la déclaration de la fonction, mais pas
les autres. C'est vraiement la seule différence, selon le
langage. Et si tu régardes les cas réels, dans la API de
Java, tu constateras que les seules qu'il faut lister, ce
sont celles qu'il faut typiquement traiter à un niveau tout
près. C-à-d celles où on se servira d'un code de rétour
d'une fonction en C++, parce que c'est quand même moins
lourd.
je suis assez d'accord; mais la lourdeur ne sera présente que
si on fait exprès d'être lourd: on peut (et il est pertinent
de) faire un test avant l'opération et sortir directement en
erreur ou on peut y aller bourrin et jouer du try/catch, e.g.
int foo(Object definedOrNot){
if (definedOrNot == null)
return -1;
return definedOrNot.g();
}
ou
int foo(Object definedOrNot){
try {
return definedOrNot.g();
}
catch (NullPointerException npe){
return -1;
}
}
les 2 sont valides, la seconde est inutilement lourde; reste
que la 'proximité' utilisée ici n'est pas toujours vérifiée;
le codeur doit faire preuve de discernement.
L'exemple typique où une exception est la solution préférée,
c'est std::bad_alloc (en C++) ou java.lang.OutOfMemoryError
(en Java). C'est un cas type où l'erreur ne pourrait pas
être traitée localement.
"le codeur doit faire preuve de discernement" ...
s'il s'agit d'une initialisation de buffer de transaction, je
ferais un traitement local pour essayer de poursuivre avec un
tampon plus petit plutôt que de jeter l'éponge.
Il y en a beaucoup de ce genre qui dérivent de
RuntimeException ; ce sont des erreurs que, si on veut les
traiter, il faut les traiter à un niveau assez élevé,
je dirais plutôt cela des Error.
En C++ (§15.4/8,9) :
Pas de distinction entre deux catégories d'exception. Et
s'il y a une exception-specification, c'est véritablement
une garantie : quoi qui arrive, on ne sort pas avec une
exception qui n'est pas citée, et si elle est vide, on ne
sort pas de la fonction avec une exception.
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
kanze wrote on 25/07/2006 09:47:Je parlais de ce qu'on appelle les « out parameters » en
anglais.
ok donc des "paramètres par référence", à moins que tu
n'inclues implicitement également le mot-clé "out" jouant sur
les régles de modifications du paramètre formel (ou pire les
modifiers de .net).
Java ne supporte ni out, ni inout.
il supporte 'final' qui agit comme 'const' pour un "in
parameter".
(Le C++, en fait, ne supporte pas réelement out non plus.
Mais on arrive aux mêmes fins avec des inout la plupart du
temps.)
match nul avec une référence Java - sauf pour changer la
valeur d'un pointeur (un "out type [const] * &").C'est un concepte assez connu, il me semble.
archi connu ! mais comme je n'ai vu aucun lien avec le point
discuté...
À titre d'exemple, essayer d'écrire l'équivalant en Java de
std::swap.
swaper quoi appartenant à qui ??
si c'est une classe clonable je ne vois pas le problème, si
c'est des types primitifs c'est également facile, si par
contre ce sont des pointeurs ... je l'ai déjà dit.
ceci étant, les map et autres ensembles triés existent (c'est
là que le "appartenant à qui" intervient), il sera donc
toujours possible de swap dans un contexte donné.
Je n'arrive pas à comprendre ce que tu ne comprends pas. Tu
sais très bien que le Java ne t'oblige à lister que
certaines exceptions, non toutes. C'est là le problème,
parce que la garantie la plus intéressante, c'est bien qu'il
n'y aura pas d'exception. Du tout. Qu'elle hérite de
RuntimeException ou de Error, ou non. C'est dans la pratique
peut-être la seule garantie un peu près utile.
je suis désolé mais justement la classe de l'exception à son
importance (tel que Java se pratique en tout cas). les erreurs
RuntimeException et Error sont réputés non récupérables - un
peu moins pour les filles de RuntimeException, mais la plupart
résulterait d'erreur ou de manque grossier dans le codage
(aucune méthode standard ne lève de telle exception par
surprise).
Idéalement, on l'aurait, et elle serait vérifiée par le
compilateur. En C++, on l'a, mais avec vérification lors de
l'exécution -- c'est loin d'être idéal, mais c'est mieux que
rien.
tu peux m'expliquer ce point ?
le code:
class Exception {
public:
Exception(int) {}
};
int foo() throw()
{
int x = 3, y = 0;
int z = x / y;
int* p = NULL;
*p = 1;
throw Exception(3);
}
a, il me semble, 3 raisons de partir en exception; si je
catche l'appel à foo par un handler générique ("...") je tombe
pour chacune d'elle (en commentant la précédante) dans mon
handler.
que signifie alors la "vérification à l'exécution" ?
il faut que je change de compilo ?
C'est à croire que tu connais ni le Java, ni le C++, parce
que tu l'a exactement à l'envers. La déclaration ci-dessus
en Java garantie seulement que la fonction ne peut pas lever
une parmi un petit sous-ensemble des exceptions. Et j'ai
déjà (souvent d'ailleurs) vu des fonctions Java avec une
déclaration pareille sortir par une exception.
une exception que tu n'as pas à déclarer car dans 99% des cas
cela ne sert à rien (VM morte, stack corrompu, etc ...) - dit
que cet indéterminisme te parait inacceptable (le cas échéant)
mais pas que ce n'est pas une garantie (ou accepte que
"garantie" ait un sens propre au langage).
Quand tu spécifies throw() sur une fonction en C++, en
revanche, tu es 100% sûr que la fonction ne sortira jamais
par une exception.
ben j'attends ta réponse sur l'exemple précédent, parce que
l'expérience me montre le contraire pour l'instant.
La seule différence entre les deux, c'est qu'il faut en
citer les unes dans la déclaration de la fonction, mais pas
les autres. C'est vraiement la seule différence, selon le
langage. Et si tu régardes les cas réels, dans la API de
Java, tu constateras que les seules qu'il faut lister, ce
sont celles qu'il faut typiquement traiter à un niveau tout
près. C-à-d celles où on se servira d'un code de rétour
d'une fonction en C++, parce que c'est quand même moins
lourd.
je suis assez d'accord; mais la lourdeur ne sera présente que
si on fait exprès d'être lourd: on peut (et il est pertinent
de) faire un test avant l'opération et sortir directement en
erreur ou on peut y aller bourrin et jouer du try/catch, e.g.
int foo(Object definedOrNot){
if (definedOrNot == null)
return -1;
return definedOrNot.g();
}
ou
int foo(Object definedOrNot){
try {
return definedOrNot.g();
}
catch (NullPointerException npe){
return -1;
}
}
les 2 sont valides, la seconde est inutilement lourde; reste
que la 'proximité' utilisée ici n'est pas toujours vérifiée;
le codeur doit faire preuve de discernement.
L'exemple typique où une exception est la solution préférée,
c'est std::bad_alloc (en C++) ou java.lang.OutOfMemoryError
(en Java). C'est un cas type où l'erreur ne pourrait pas
être traitée localement.
"le codeur doit faire preuve de discernement" ...
s'il s'agit d'une initialisation de buffer de transaction, je
ferais un traitement local pour essayer de poursuivre avec un
tampon plus petit plutôt que de jeter l'éponge.
Il y en a beaucoup de ce genre qui dérivent de
RuntimeException ; ce sont des erreurs que, si on veut les
traiter, il faut les traiter à un niveau assez élevé,
je dirais plutôt cela des Error.
En C++ (§15.4/8,9) :
Pas de distinction entre deux catégories d'exception. Et
s'il y a une exception-specification, c'est véritablement
une garantie : quoi qui arrive, on ne sort pas avec une
exception qui n'est pas citée, et si elle est vide, on ne
sort pas de la fonction avec une exception.
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
Je parlais d'un concepte, non d'une technique d'implémentation.
...
Parce qu'archi connu ou non, tu ne le comprends pas.
À titre d'exemple, essayer d'écrire l'équivalant en Java de
std::swap.
...
On veut les échanger. Je ne vois pas ce qu'il y a de si
compliqué à comprendre là-dedans.
(Quand je parle de RuntimeException ou de Error, j'entends
évidemment les classes dérivées.)
D'abord, il y a bien des cas où elles sont récupérables ;
beaucoup d'applications de C++ récupèrent des manques de
mémoire (OutOfMemory, en Java, qui dérive de Error).
La distinction n'est pas vraiment claire et nette. Et si
une erreur n'est pas récupérable, pourquoi lever une exception ?
Le fait reste que je sors de la fonction par une exception, et
il n'y a rien que je peux dire ni faire au niveau de la
*spécification formelle* de la fonction pour garantir que ça ne
se produit pas. Il n'y a que la documentation, et si le code ne
s'y conforme pas, tant pis
je n'ai aucun moyen simple non plus
d'y ajouter des vérifications du contrat.
int foo() throw()
{
throw Exception(3);
}
Les deux premières erreurs sont des comportements indéfinis.
En ce qui concerne la troisième, le langage est clair. Il faut
que la fonction unexpected() soit appelée, qui, par défaut
appelle terminate(), qui par défaut appelle abort(). Et là
aussi, les compilateurs auxquels j'ai accès sont tous
conforment.
[...] « /EHs /GR » pour VC++
VC++ [..] émet un avertissement lors de la compilation :
« function assumed not to throw an exception but does ».
Alors, tu n'as pas d'expérience avec un compilateur C++.
[...] VC++ 6.0 traite la spécification d'exception
correctement, vue la volatilité qu'elle a eu pendant
la normalisation. Et la génération des core dumps [...]
Et qui est assez naïf pour croire aux promesses du marketing ?
Il y en a beaucoup de ce genre qui dérivent de
RuntimeException ; ce sont des erreurs que, si on veut les
traiter, il faut les traiter à un niveau assez élevé,
je dirais plutôt cela des Error.
Tel que je l'avais compris, j'aurais cru que normalement Error,
c'est les exceptions que tu ne dois jamais attraper (et qui,
AMHA, ne doit pas être des exceptions, mais des avorts),
RuntimeException celles que tu dois attraper au plus haut
niveau, et les autres, celles qu'on peut souvent traiter
localement (et qui serait mieux comme code de retour).
j'avoue que les exceptions qu'on trouver réelement dans chaque
hièrarchie n'y correspondent pas, et qu'on fait, il me semble
qu'il y a beaucoup d'arbitraire :
j'ai du mal à voir OutOfMemory comme une
VirtualMachineError (et donc une Error), par exemple.
les préciser partout. En revanche, pour les quelques fonctions
où on a besoin de garantir aucune exceptions, sans exception,
c'est vraiment dommage que la possibilité de le spécifier
n'existe pas.
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
En effet, il faudra que tu changes de compilateur. Je serais
même curieux ce que tu as comme compilateur.
Je parlais d'un concepte, non d'une technique d'implémentation.
...
Parce qu'archi connu ou non, tu ne le comprends pas.
À titre d'exemple, essayer d'écrire l'équivalant en Java de
std::swap.
...
On veut les échanger. Je ne vois pas ce qu'il y a de si
compliqué à comprendre là-dedans.
(Quand je parle de RuntimeException ou de Error, j'entends
évidemment les classes dérivées.)
D'abord, il y a bien des cas où elles sont récupérables ;
beaucoup d'applications de C++ récupèrent des manques de
mémoire (OutOfMemory, en Java, qui dérive de Error).
La distinction n'est pas vraiment claire et nette. Et si
une erreur n'est pas récupérable, pourquoi lever une exception ?
Le fait reste que je sors de la fonction par une exception, et
il n'y a rien que je peux dire ni faire au niveau de la
*spécification formelle* de la fonction pour garantir que ça ne
se produit pas. Il n'y a que la documentation, et si le code ne
s'y conforme pas, tant pis
je n'ai aucun moyen simple non plus
d'y ajouter des vérifications du contrat.
int foo() throw()
{
throw Exception(3);
}
Les deux premières erreurs sont des comportements indéfinis.
En ce qui concerne la troisième, le langage est clair. Il faut
que la fonction unexpected() soit appelée, qui, par défaut
appelle terminate(), qui par défaut appelle abort(). Et là
aussi, les compilateurs auxquels j'ai accès sont tous
conforment.
[...] « /EHs /GR » pour VC++
VC++ [..] émet un avertissement lors de la compilation :
« function assumed not to throw an exception but does ».
Alors, tu n'as pas d'expérience avec un compilateur C++.
[...] VC++ 6.0 traite la spécification d'exception
correctement, vue la volatilité qu'elle a eu pendant
la normalisation. Et la génération des core dumps [...]
Et qui est assez naïf pour croire aux promesses du marketing ?
Il y en a beaucoup de ce genre qui dérivent de
RuntimeException ; ce sont des erreurs que, si on veut les
traiter, il faut les traiter à un niveau assez élevé,
je dirais plutôt cela des Error.
Tel que je l'avais compris, j'aurais cru que normalement Error,
c'est les exceptions que tu ne dois jamais attraper (et qui,
AMHA, ne doit pas être des exceptions, mais des avorts),
RuntimeException celles que tu dois attraper au plus haut
niveau, et les autres, celles qu'on peut souvent traiter
localement (et qui serait mieux comme code de retour).
j'avoue que les exceptions qu'on trouver réelement dans chaque
hièrarchie n'y correspondent pas, et qu'on fait, il me semble
qu'il y a beaucoup d'arbitraire :
j'ai du mal à voir OutOfMemory comme une
VirtualMachineError (et donc une Error), par exemple.
les préciser partout. En revanche, pour les quelques fonctions
où on a besoin de garantir aucune exceptions, sans exception,
c'est vraiment dommage que la possibilité de le spécifier
n'existe pas.
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
En effet, il faudra que tu changes de compilateur. Je serais
même curieux ce que tu as comme compilateur.
Je parlais d'un concepte, non d'une technique d'implémentation.
...
Parce qu'archi connu ou non, tu ne le comprends pas.
À titre d'exemple, essayer d'écrire l'équivalant en Java de
std::swap.
...
On veut les échanger. Je ne vois pas ce qu'il y a de si
compliqué à comprendre là-dedans.
(Quand je parle de RuntimeException ou de Error, j'entends
évidemment les classes dérivées.)
D'abord, il y a bien des cas où elles sont récupérables ;
beaucoup d'applications de C++ récupèrent des manques de
mémoire (OutOfMemory, en Java, qui dérive de Error).
La distinction n'est pas vraiment claire et nette. Et si
une erreur n'est pas récupérable, pourquoi lever une exception ?
Le fait reste que je sors de la fonction par une exception, et
il n'y a rien que je peux dire ni faire au niveau de la
*spécification formelle* de la fonction pour garantir que ça ne
se produit pas. Il n'y a que la documentation, et si le code ne
s'y conforme pas, tant pis
je n'ai aucun moyen simple non plus
d'y ajouter des vérifications du contrat.
int foo() throw()
{
throw Exception(3);
}
Les deux premières erreurs sont des comportements indéfinis.
En ce qui concerne la troisième, le langage est clair. Il faut
que la fonction unexpected() soit appelée, qui, par défaut
appelle terminate(), qui par défaut appelle abort(). Et là
aussi, les compilateurs auxquels j'ai accès sont tous
conforment.
[...] « /EHs /GR » pour VC++
VC++ [..] émet un avertissement lors de la compilation :
« function assumed not to throw an exception but does ».
Alors, tu n'as pas d'expérience avec un compilateur C++.
[...] VC++ 6.0 traite la spécification d'exception
correctement, vue la volatilité qu'elle a eu pendant
la normalisation. Et la génération des core dumps [...]
Et qui est assez naïf pour croire aux promesses du marketing ?
Il y en a beaucoup de ce genre qui dérivent de
RuntimeException ; ce sont des erreurs que, si on veut les
traiter, il faut les traiter à un niveau assez élevé,
je dirais plutôt cela des Error.
Tel que je l'avais compris, j'aurais cru que normalement Error,
c'est les exceptions que tu ne dois jamais attraper (et qui,
AMHA, ne doit pas être des exceptions, mais des avorts),
RuntimeException celles que tu dois attraper au plus haut
niveau, et les autres, celles qu'on peut souvent traiter
localement (et qui serait mieux comme code de retour).
j'avoue que les exceptions qu'on trouver réelement dans chaque
hièrarchie n'y correspondent pas, et qu'on fait, il me semble
qu'il y a beaucoup d'arbitraire :
j'ai du mal à voir OutOfMemory comme une
VirtualMachineError (et donc une Error), par exemple.
les préciser partout. En revanche, pour les quelques fonctions
où on a besoin de garantir aucune exceptions, sans exception,
c'est vraiment dommage que la possibilité de le spécifier
n'existe pas.
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
En effet, il faudra que tu changes de compilateur. Je serais
même curieux ce que tu as comme compilateur.
VC++ [..] émet un avertissement lors de la compilation :
« function assumed not to throw an exception but does ».
quelle version (de cl) ?
ici cl 12 comme 14 (Studio 98 et 2005 (professional edition)) ont le
même comportement et throw bien une 'Exception' catchable.
VC++ [..] émet un avertissement lors de la compilation :
« function assumed not to throw an exception but does ».
quelle version (de cl) ?
ici cl 12 comme 14 (Studio 98 et 2005 (professional edition)) ont le
même comportement et throw bien une 'Exception' catchable.
VC++ [..] émet un avertissement lors de la compilation :
« function assumed not to throw an exception but does ».
quelle version (de cl) ?
ici cl 12 comme 14 (Studio 98 et 2005 (professional edition)) ont le
même comportement et throw bien une 'Exception' catchable.
kanze wrote on 26/07/2006 11:42:À titre d'exemple, essayer d'écrire l'équivalant en Java de
std::swap.
...
On veut les échanger. Je ne vois pas ce qu'il y a de si
compliqué à comprendre là-dedans.
j'ai pas dit compliqué, j'ai dit ça dépends du type !
pour swapper 2 int, on le fera localement en récrivant à chaque fois la
function idoine, on n'utilisera pas un unique template soit, mais comme
tu le dis "c'est pas trop génant", la philosophie (les obligeations
plutôt) de Java n'est pas aux templates c'est tout (hormi pour un
vecteur ou une liste).
de mon expérience je dirais qu'une appli (la partie code à
soi) n'utilise jamais de RuntimeException (car on sait et/ou
vérifie ce que l'on fait)
La distinction n'est pas vraiment claire et nette. Et si une
erreur n'est pas récupérable, pourquoi lever une exception ?
pour essayer quand même de sauver ce qui peut l'être ? parce
que la règle de parfois abuser des throw ? ...
je n'ai aucun moyen simple non plus
d'y ajouter des vérifications du contrat.
ça dépends ce que tu entends par ajouter; si tu as des doutes
sur le respect du contrat tu peux surrounder par un try/catch.
En ce qui concerne la troisième, le langage est clair. Il
faut que la fonction unexpected() soit appelée, qui, par
défaut appelle terminate(), qui par défaut appelle abort().
Et là aussi, les compilateurs auxquels j'ai accès sont tous
conforment.
vc8 (Studio2005, cl 14.0.50727.42) est conforme, vc6 (Studio98, cl
12.0.8168.0) ne l'est pas.
[...] « /EHs /GR » pour VC++
ce sont les réglages pour les 2: /GR pour les infos RTTI et
/GX (ou /EH[sc]) pour les exceptions C++.
VC++ [..] émet un avertissement lors de la compilation :
« function assumed not to throw an exception but does ».
quelle version (de cl) ?
Alors, tu n'as pas d'expérience avec un compilateur C++.
[...] VC++ 6.0 traite la spécification d'exception
correctement, vue la volatilité qu'elle a eu pendant la
normalisation. Et la génération des core dumps [...]
si j'ai un peu d'expérience des compilo VC (trop même prenant
ces extensions pour un standard); il traite incorrectement et
ignore passablement ce qu'est un core dump (notion très
linux).
Tel que je l'avais compris, j'aurais cru que normalement Error,
c'est les exceptions que tu ne dois jamais attraper (et qui,
AMHA, ne doit pas être des exceptions, mais des avorts),
oui, mais comme abort n'étant pas la règle (sauf si la VM
complète explose), tu peux vouloir traiter les Error très haut
pour choisir entre continuer (peut être en ayant perdu tous
les docs, fichiers, etc) ou en effet aborter l'appli.
j'ai du mal à voir OutOfMemory comme une
VirtualMachineError (et donc une Error), par exemple.
je le disais plus haut, c'est parce que ""idéalement"" il y a
tjrs de la mémoire (virtuelle) dispo. ce "OutOfMemory" là ne
correspond pas aux limites tiny, small, huge du C d'antan (en
imaginant que ce n'étaient pas que des modèles mémoires du
monde Intel).
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
En effet, il faudra que tu changes de compilateur. Je serais
même curieux ce que tu as comme compilateur.
ici cl 12 comme 14 (Studio 98 et 2005 (professional edition))
ont le même comportement et throw bien une 'Exception'
catchable.
c'était mon point initial! ces compilos n'utilisent pas du
tout les exceptions présentes dans la déclaration - vc2005 a
"seulement" ajouter la gestion correcte du 'nothrow'.
kanze wrote on 26/07/2006 11:42:
À titre d'exemple, essayer d'écrire l'équivalant en Java de
std::swap.
...
On veut les échanger. Je ne vois pas ce qu'il y a de si
compliqué à comprendre là-dedans.
j'ai pas dit compliqué, j'ai dit ça dépends du type !
pour swapper 2 int, on le fera localement en récrivant à chaque fois la
function idoine, on n'utilisera pas un unique template soit, mais comme
tu le dis "c'est pas trop génant", la philosophie (les obligeations
plutôt) de Java n'est pas aux templates c'est tout (hormi pour un
vecteur ou une liste).
de mon expérience je dirais qu'une appli (la partie code à
soi) n'utilise jamais de RuntimeException (car on sait et/ou
vérifie ce que l'on fait)
La distinction n'est pas vraiment claire et nette. Et si une
erreur n'est pas récupérable, pourquoi lever une exception ?
pour essayer quand même de sauver ce qui peut l'être ? parce
que la règle de parfois abuser des throw ? ...
je n'ai aucun moyen simple non plus
d'y ajouter des vérifications du contrat.
ça dépends ce que tu entends par ajouter; si tu as des doutes
sur le respect du contrat tu peux surrounder par un try/catch.
En ce qui concerne la troisième, le langage est clair. Il
faut que la fonction unexpected() soit appelée, qui, par
défaut appelle terminate(), qui par défaut appelle abort().
Et là aussi, les compilateurs auxquels j'ai accès sont tous
conforment.
vc8 (Studio2005, cl 14.0.50727.42) est conforme, vc6 (Studio98, cl
12.0.8168.0) ne l'est pas.
[...] « /EHs /GR » pour VC++
ce sont les réglages pour les 2: /GR pour les infos RTTI et
/GX (ou /EH[sc]) pour les exceptions C++.
VC++ [..] émet un avertissement lors de la compilation :
« function assumed not to throw an exception but does ».
quelle version (de cl) ?
Alors, tu n'as pas d'expérience avec un compilateur C++.
[...] VC++ 6.0 traite la spécification d'exception
correctement, vue la volatilité qu'elle a eu pendant la
normalisation. Et la génération des core dumps [...]
si j'ai un peu d'expérience des compilo VC (trop même prenant
ces extensions pour un standard); il traite incorrectement et
ignore passablement ce qu'est un core dump (notion très
linux).
Tel que je l'avais compris, j'aurais cru que normalement Error,
c'est les exceptions que tu ne dois jamais attraper (et qui,
AMHA, ne doit pas être des exceptions, mais des avorts),
oui, mais comme abort n'étant pas la règle (sauf si la VM
complète explose), tu peux vouloir traiter les Error très haut
pour choisir entre continuer (peut être en ayant perdu tous
les docs, fichiers, etc) ou en effet aborter l'appli.
j'ai du mal à voir OutOfMemory comme une
VirtualMachineError (et donc une Error), par exemple.
je le disais plus haut, c'est parce que ""idéalement"" il y a
tjrs de la mémoire (virtuelle) dispo. ce "OutOfMemory" là ne
correspond pas aux limites tiny, small, huge du C d'antan (en
imaginant que ce n'étaient pas que des modèles mémoires du
monde Intel).
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
En effet, il faudra que tu changes de compilateur. Je serais
même curieux ce que tu as comme compilateur.
ici cl 12 comme 14 (Studio 98 et 2005 (professional edition))
ont le même comportement et throw bien une 'Exception'
catchable.
c'était mon point initial! ces compilos n'utilisent pas du
tout les exceptions présentes dans la déclaration - vc2005 a
"seulement" ajouter la gestion correcte du 'nothrow'.
kanze wrote on 26/07/2006 11:42:À titre d'exemple, essayer d'écrire l'équivalant en Java de
std::swap.
...
On veut les échanger. Je ne vois pas ce qu'il y a de si
compliqué à comprendre là-dedans.
j'ai pas dit compliqué, j'ai dit ça dépends du type !
pour swapper 2 int, on le fera localement en récrivant à chaque fois la
function idoine, on n'utilisera pas un unique template soit, mais comme
tu le dis "c'est pas trop génant", la philosophie (les obligeations
plutôt) de Java n'est pas aux templates c'est tout (hormi pour un
vecteur ou une liste).
de mon expérience je dirais qu'une appli (la partie code à
soi) n'utilise jamais de RuntimeException (car on sait et/ou
vérifie ce que l'on fait)
La distinction n'est pas vraiment claire et nette. Et si une
erreur n'est pas récupérable, pourquoi lever une exception ?
pour essayer quand même de sauver ce qui peut l'être ? parce
que la règle de parfois abuser des throw ? ...
je n'ai aucun moyen simple non plus
d'y ajouter des vérifications du contrat.
ça dépends ce que tu entends par ajouter; si tu as des doutes
sur le respect du contrat tu peux surrounder par un try/catch.
En ce qui concerne la troisième, le langage est clair. Il
faut que la fonction unexpected() soit appelée, qui, par
défaut appelle terminate(), qui par défaut appelle abort().
Et là aussi, les compilateurs auxquels j'ai accès sont tous
conforment.
vc8 (Studio2005, cl 14.0.50727.42) est conforme, vc6 (Studio98, cl
12.0.8168.0) ne l'est pas.
[...] « /EHs /GR » pour VC++
ce sont les réglages pour les 2: /GR pour les infos RTTI et
/GX (ou /EH[sc]) pour les exceptions C++.
VC++ [..] émet un avertissement lors de la compilation :
« function assumed not to throw an exception but does ».
quelle version (de cl) ?
Alors, tu n'as pas d'expérience avec un compilateur C++.
[...] VC++ 6.0 traite la spécification d'exception
correctement, vue la volatilité qu'elle a eu pendant la
normalisation. Et la génération des core dumps [...]
si j'ai un peu d'expérience des compilo VC (trop même prenant
ces extensions pour un standard); il traite incorrectement et
ignore passablement ce qu'est un core dump (notion très
linux).
Tel que je l'avais compris, j'aurais cru que normalement Error,
c'est les exceptions que tu ne dois jamais attraper (et qui,
AMHA, ne doit pas être des exceptions, mais des avorts),
oui, mais comme abort n'étant pas la règle (sauf si la VM
complète explose), tu peux vouloir traiter les Error très haut
pour choisir entre continuer (peut être en ayant perdu tous
les docs, fichiers, etc) ou en effet aborter l'appli.
j'ai du mal à voir OutOfMemory comme une
VirtualMachineError (et donc une Error), par exemple.
je le disais plus haut, c'est parce que ""idéalement"" il y a
tjrs de la mémoire (virtuelle) dispo. ce "OutOfMemory" là ne
correspond pas aux limites tiny, small, huge du C d'antan (en
imaginant que ce n'étaient pas que des modèles mémoires du
monde Intel).
il faut vraiment que je change de compilo alors:
int foo() throw(ExceptionOther){
throw Exception(3);
}
sort avec une 'Exception' ...
En effet, il faudra que tu changes de compilateur. Je serais
même curieux ce que tu as comme compilateur.
ici cl 12 comme 14 (Studio 98 et 2005 (professional edition))
ont le même comportement et throw bien une 'Exception'
catchable.
c'était mon point initial! ces compilos n'utilisent pas du
tout les exceptions présentes dans la déclaration - vc2005 a
"seulement" ajouter la gestion correcte du 'nothrow'.