Bonjour,
je débute dans l'utilisation des assert et autres try-catch et je bloque
sur l'affichage du fichier et de la ligne de l'erreur car __FILE__ et
__LINE__ ne sont pas évaluées là où je le souhaiterai.
Olm_Scalar& operator/=(const Olm_Scalar& s) // en inline !!!
try{ if (s.x==0.0) throw Olm_Error("division by
0",__FILE__,__LINE__); x/=s.x; return *this; }
Bonjour,
je débute dans l'utilisation des assert et autres try-catch et je bloque
sur l'affichage du fichier et de la ligne de l'erreur car __FILE__ et
__LINE__ ne sont pas évaluées là où je le souhaiterai.
Olm_Scalar& operator/=(const Olm_Scalar& s) // en inline !!!
try{ if (s.x==0.0) throw Olm_Error("division by
0",__FILE__,__LINE__); x/=s.x; return *this; }
Bonjour,
je débute dans l'utilisation des assert et autres try-catch et je bloque
sur l'affichage du fichier et de la ligne de l'erreur car __FILE__ et
__LINE__ ne sont pas évaluées là où je le souhaiterai.
Olm_Scalar& operator/=(const Olm_Scalar& s) // en inline !!!
try{ if (s.x==0.0) throw Olm_Error("division by
0",__FILE__,__LINE__); x/=s.x; return *this; }
je débute dans l'utilisation des assert et autres try-catch et je bloque sur
l'affichage du fichier et de la ligne de l'erreur car __FILE__ et __LINE__ ne
sont pas évaluées là où je le souhaiterai.
je débute dans l'utilisation des assert et autres try-catch et je bloque sur
l'affichage du fichier et de la ligne de l'erreur car __FILE__ et __LINE__ ne
sont pas évaluées là où je le souhaiterai.
je débute dans l'utilisation des assert et autres try-catch et je bloque sur
l'affichage du fichier et de la ligne de l'erreur car __FILE__ et __LINE__ ne
sont pas évaluées là où je le souhaiterai.
Aurélien Barbier-Accary wrote:je débute dans l'utilisation des assert et autres try-catch
et je bloque sur l'affichage du fichier et de la ligne de
l'erreur car __FILE__ et __LINE__ ne sont pas évaluées là où
je le souhaiterai. Olm_Scalar& operator/=(const Olm_Scalar&
s) // en inline !!! try{ if (s.x==0.0) throw
Olm_Error("division by 0",__FILE__,__LINE__); x/=s.x; return
*this; }
Une solution est de definir une macro dans ton olm_error.hpp:
#define OLM_ERROR(text) Olm_Error(text, __FILE__, __LINE__)
et de l'utiliser pour lancer l'exception:
throw OLM_ERROR("division by 0");
Aurélien Barbier-Accary wrote:
je débute dans l'utilisation des assert et autres try-catch
et je bloque sur l'affichage du fichier et de la ligne de
l'erreur car __FILE__ et __LINE__ ne sont pas évaluées là où
je le souhaiterai. Olm_Scalar& operator/=(const Olm_Scalar&
s) // en inline !!! try{ if (s.x==0.0) throw
Olm_Error("division by 0",__FILE__,__LINE__); x/=s.x; return
*this; }
Une solution est de definir une macro dans ton olm_error.hpp:
#define OLM_ERROR(text) Olm_Error(text, __FILE__, __LINE__)
et de l'utiliser pour lancer l'exception:
throw OLM_ERROR("division by 0");
Aurélien Barbier-Accary wrote:je débute dans l'utilisation des assert et autres try-catch
et je bloque sur l'affichage du fichier et de la ligne de
l'erreur car __FILE__ et __LINE__ ne sont pas évaluées là où
je le souhaiterai. Olm_Scalar& operator/=(const Olm_Scalar&
s) // en inline !!! try{ if (s.x==0.0) throw
Olm_Error("division by 0",__FILE__,__LINE__); x/=s.x; return
*this; }
Une solution est de definir une macro dans ton olm_error.hpp:
#define OLM_ERROR(text) Olm_Error(text, __FILE__, __LINE__)
et de l'utiliser pour lancer l'exception:
throw OLM_ERROR("division by 0");
Une solution est de definir une macro dans ton olm_error.hpp:
#define OLM_ERROR(text) Olm_Error(text, __FILE__, __LINE__)
et de l'utiliser pour lancer l'exception:
throw OLM_ERROR("division by 0");
HTH,
Philippe
Une solution est de definir une macro dans ton olm_error.hpp:
#define OLM_ERROR(text) Olm_Error(text, __FILE__, __LINE__)
et de l'utiliser pour lancer l'exception:
throw OLM_ERROR("division by 0");
HTH,
Philippe
Une solution est de definir une macro dans ton olm_error.hpp:
#define OLM_ERROR(text) Olm_Error(text, __FILE__, __LINE__)
et de l'utiliser pour lancer l'exception:
throw OLM_ERROR("division by 0");
HTH,
Philippe
... Son problème, c'est qu'il
detecte le problème dans une fonction, et le nom de fichier et
le numéro de la ligne qui l'intéresse, ce sont ceux de l'appel
de la fonction.
tout à fait
On pourrait poser la question si les exceptions sont le
mechanisme qui convient ici, mais le problème se pose de la même
façon pour les logs ou les messages en cas d'erreur fatale. Et
en fait, autant que je sache, il n'y a que deux solutions
possibles : faire passer l'information par l'appelant, ou
remonter la pile pour trouver les adresses de rétour, puis à
partir de ces adresses, trouver où on était.
Or, la première solution ne peut pas réelement servir dans le
cas des opérateurs, et même dans les autres cas, introduit des
contraints au niveau de l'utilisateur (paramètre supplémentaire
qui est en fait un macro, etc.). Et la deuxième a besoin du code
qui dépend de l'implémentation. J'ai une classe qui remonte bien
la pile, mais le code de l'implémentation n'est pas le même
selon l'architecture, et même parfois le compilateur, la version
de l'OS, etc. En plus, il ne sort que les adresses
hexadécimales.
... Son problème, c'est qu'il
detecte le problème dans une fonction, et le nom de fichier et
le numéro de la ligne qui l'intéresse, ce sont ceux de l'appel
de la fonction.
tout à fait
On pourrait poser la question si les exceptions sont le
mechanisme qui convient ici, mais le problème se pose de la même
façon pour les logs ou les messages en cas d'erreur fatale. Et
en fait, autant que je sache, il n'y a que deux solutions
possibles : faire passer l'information par l'appelant, ou
remonter la pile pour trouver les adresses de rétour, puis à
partir de ces adresses, trouver où on était.
Or, la première solution ne peut pas réelement servir dans le
cas des opérateurs, et même dans les autres cas, introduit des
contraints au niveau de l'utilisateur (paramètre supplémentaire
qui est en fait un macro, etc.). Et la deuxième a besoin du code
qui dépend de l'implémentation. J'ai une classe qui remonte bien
la pile, mais le code de l'implémentation n'est pas le même
selon l'architecture, et même parfois le compilateur, la version
de l'OS, etc. En plus, il ne sort que les adresses
hexadécimales.
... Son problème, c'est qu'il
detecte le problème dans une fonction, et le nom de fichier et
le numéro de la ligne qui l'intéresse, ce sont ceux de l'appel
de la fonction.
tout à fait
On pourrait poser la question si les exceptions sont le
mechanisme qui convient ici, mais le problème se pose de la même
façon pour les logs ou les messages en cas d'erreur fatale. Et
en fait, autant que je sache, il n'y a que deux solutions
possibles : faire passer l'information par l'appelant, ou
remonter la pile pour trouver les adresses de rétour, puis à
partir de ces adresses, trouver où on était.
Or, la première solution ne peut pas réelement servir dans le
cas des opérateurs, et même dans les autres cas, introduit des
contraints au niveau de l'utilisateur (paramètre supplémentaire
qui est en fait un macro, etc.). Et la deuxième a besoin du code
qui dépend de l'implémentation. J'ai une classe qui remonte bien
la pile, mais le code de l'implémentation n'est pas le même
selon l'architecture, et même parfois le compilateur, la version
de l'OS, etc. En plus, il ne sort que les adresses
hexadécimales.
... Son problème, c'est qu'il detecte le problème dans une
fonction, et le nom de fichier et le numéro de la ligne qui
l'intéresse, ce sont ceux de l'appel de la fonction.
tout à faitOn pourrait poser la question si les exceptions sont le
mechanisme qui convient ici, mais le problème se pose de la
même façon pour les logs ou les messages en cas d'erreur
fatale. Et en fait, autant que je sache, il n'y a que deux
solutions possibles : faire passer l'information par
l'appelant, ou remonter la pile pour trouver les adresses de
rétour, puis à partir de ces adresses, trouver où on était.
Or, la première solution ne peut pas réelement servir dans
le cas des opérateurs, et même dans les autres cas,
introduit des contraints au niveau de l'utilisateur
(paramètre supplémentaire qui est en fait un macro, etc.).
Et la deuxième a besoin du code qui dépend de
l'implémentation. J'ai une classe qui remonte bien la pile,
mais le code de l'implémentation n'est pas le même selon
l'architecture, et même parfois le compilateur, la version
de l'OS, etc. En plus, il ne sort que les adresses
hexadécimales.
Tout d'abord merci pour cette réponse détaillée.
Jusqu'ici je gérais les erreurs "à la main" par des bêtes
if (pb)
{
std::cerr << "PB" << std::endl;
exit(1);
}
mais je déplorais le fait d'être obligé de recourir à gdb ou
autre en cas de pb puisque cela impose de travailler au sein
d'un environnement particulier et en mode debug.
Là je cherche à définir des libs capables de garantir la
robustesse des calculs et en cas de mauvaise utilisation de
prévenir l'utilisateur et de l'informer sur la source
effective de son erreur.
Donc ma question est: "quel est alors l'intérêt des
exceptions" ?
On pourrait répondre que ça permet une lecture sémantique plus
agréable du code ou encore que ça autorise une gestion
internationalisée des messages d'erreur mais je crois pour ma
part qu'un message d'erreur du genre "division par 0 -> fin"
est totalement inutile si on n'a pas plus d'information sur la
source du problème.
Je suis perplexe...
Pour revenir à tes remarques, effectivement il n'est pas
envisageable de faire passer ces informations par l'appelant.
Pour ce qui est de remonter la pile, une seule étape serait
déjà une bonne chose et je pensais que les exceptions
"intégraient" ce mécanisme en gérant l'erreur à partir de
l'appelant et non pas dans la fonction appelée (au moins pour
les opérateurs !) :-(
Pour info, en quelques mots comment fonctionne ta classe qui
remonte la pile ?
Dois-tu passer l'adresse de l'appelant à chaque fonction ? Si
oui comment gères-tu les opérateurs ?
... Son problème, c'est qu'il detecte le problème dans une
fonction, et le nom de fichier et le numéro de la ligne qui
l'intéresse, ce sont ceux de l'appel de la fonction.
tout à fait
On pourrait poser la question si les exceptions sont le
mechanisme qui convient ici, mais le problème se pose de la
même façon pour les logs ou les messages en cas d'erreur
fatale. Et en fait, autant que je sache, il n'y a que deux
solutions possibles : faire passer l'information par
l'appelant, ou remonter la pile pour trouver les adresses de
rétour, puis à partir de ces adresses, trouver où on était.
Or, la première solution ne peut pas réelement servir dans
le cas des opérateurs, et même dans les autres cas,
introduit des contraints au niveau de l'utilisateur
(paramètre supplémentaire qui est en fait un macro, etc.).
Et la deuxième a besoin du code qui dépend de
l'implémentation. J'ai une classe qui remonte bien la pile,
mais le code de l'implémentation n'est pas le même selon
l'architecture, et même parfois le compilateur, la version
de l'OS, etc. En plus, il ne sort que les adresses
hexadécimales.
Tout d'abord merci pour cette réponse détaillée.
Jusqu'ici je gérais les erreurs "à la main" par des bêtes
if (pb)
{
std::cerr << "PB" << std::endl;
exit(1);
}
mais je déplorais le fait d'être obligé de recourir à gdb ou
autre en cas de pb puisque cela impose de travailler au sein
d'un environnement particulier et en mode debug.
Là je cherche à définir des libs capables de garantir la
robustesse des calculs et en cas de mauvaise utilisation de
prévenir l'utilisateur et de l'informer sur la source
effective de son erreur.
Donc ma question est: "quel est alors l'intérêt des
exceptions" ?
On pourrait répondre que ça permet une lecture sémantique plus
agréable du code ou encore que ça autorise une gestion
internationalisée des messages d'erreur mais je crois pour ma
part qu'un message d'erreur du genre "division par 0 -> fin"
est totalement inutile si on n'a pas plus d'information sur la
source du problème.
Je suis perplexe...
Pour revenir à tes remarques, effectivement il n'est pas
envisageable de faire passer ces informations par l'appelant.
Pour ce qui est de remonter la pile, une seule étape serait
déjà une bonne chose et je pensais que les exceptions
"intégraient" ce mécanisme en gérant l'erreur à partir de
l'appelant et non pas dans la fonction appelée (au moins pour
les opérateurs !) :-(
Pour info, en quelques mots comment fonctionne ta classe qui
remonte la pile ?
Dois-tu passer l'adresse de l'appelant à chaque fonction ? Si
oui comment gères-tu les opérateurs ?
... Son problème, c'est qu'il detecte le problème dans une
fonction, et le nom de fichier et le numéro de la ligne qui
l'intéresse, ce sont ceux de l'appel de la fonction.
tout à faitOn pourrait poser la question si les exceptions sont le
mechanisme qui convient ici, mais le problème se pose de la
même façon pour les logs ou les messages en cas d'erreur
fatale. Et en fait, autant que je sache, il n'y a que deux
solutions possibles : faire passer l'information par
l'appelant, ou remonter la pile pour trouver les adresses de
rétour, puis à partir de ces adresses, trouver où on était.
Or, la première solution ne peut pas réelement servir dans
le cas des opérateurs, et même dans les autres cas,
introduit des contraints au niveau de l'utilisateur
(paramètre supplémentaire qui est en fait un macro, etc.).
Et la deuxième a besoin du code qui dépend de
l'implémentation. J'ai une classe qui remonte bien la pile,
mais le code de l'implémentation n'est pas le même selon
l'architecture, et même parfois le compilateur, la version
de l'OS, etc. En plus, il ne sort que les adresses
hexadécimales.
Tout d'abord merci pour cette réponse détaillée.
Jusqu'ici je gérais les erreurs "à la main" par des bêtes
if (pb)
{
std::cerr << "PB" << std::endl;
exit(1);
}
mais je déplorais le fait d'être obligé de recourir à gdb ou
autre en cas de pb puisque cela impose de travailler au sein
d'un environnement particulier et en mode debug.
Là je cherche à définir des libs capables de garantir la
robustesse des calculs et en cas de mauvaise utilisation de
prévenir l'utilisateur et de l'informer sur la source
effective de son erreur.
Donc ma question est: "quel est alors l'intérêt des
exceptions" ?
On pourrait répondre que ça permet une lecture sémantique plus
agréable du code ou encore que ça autorise une gestion
internationalisée des messages d'erreur mais je crois pour ma
part qu'un message d'erreur du genre "division par 0 -> fin"
est totalement inutile si on n'a pas plus d'information sur la
source du problème.
Je suis perplexe...
Pour revenir à tes remarques, effectivement il n'est pas
envisageable de faire passer ces informations par l'appelant.
Pour ce qui est de remonter la pile, une seule étape serait
déjà une bonne chose et je pensais que les exceptions
"intégraient" ce mécanisme en gérant l'erreur à partir de
l'appelant et non pas dans la fonction appelée (au moins pour
les opérateurs !) :-(
Pour info, en quelques mots comment fonctionne ta classe qui
remonte la pile ?
Dois-tu passer l'adresse de l'appelant à chaque fonction ? Si
oui comment gères-tu les opérateurs ?