OVH Cloud OVH Cloud

renseignement sur throw et son fonctionnement

15 réponses
Avatar
Stephane Wirtel
bonsoir,

simplement pour m'amuser, je viens de créer une classe d'exception
n'héritant pas d'une std::exception & co.

je l'ai rendue non copyable, mais j'ai constaté que le compilo (g++ 4.1)
râlait quand je lançais mon exception via throw.

le code est tout simple

<code exemple>

#include <string>
#include <boost/noncopyable.hpp>

/// La classe est rendue non copyable pour faire un test qui je pensais
/// allait réussir.
class MonException : boost::noncopyable {
public:
MonException( const std::string & msg_ ) : msg( msg_ ) {
}
private:
std::string msg;
};


int main( int argc, char ** argv ) {
try {
/// création d'une instance d'une classe
throw MonException("ceci est un test");
}
catch( const MonException & ex ) {
/// on catche une référence sur l'instance MonException qui a été
/// lancée
}
return 0;
}
</code>

Lors de la compilation, je constate que le compilateur essaye de créer
un constructeur de copie, alors que je l'interdit.

Est-ce dans la norme de créer une nouvelle instance de la classe par un
constructeur de copie ou est-ce un probleme dans le configuration de la
phase de compilation ?

Merci

5 réponses

1 2
Avatar
Fabien LE LEZ
On Tue, 12 Sep 2006 10:50:10 +0200, Alain Gaillard
:

Si l'exception relancée est capturée plus loin et comme ça:

catch(exception e)

il y a copie.


Ce qui est logique, puisque tu demandes un passage à valeur à catch.
Si par contre tu écris

catch (exception const& e)

tu as vraisemblablement une copie de moins. Et en plus, what()
fonctionne.

Avatar
Alain Gaillard


Ce qui est logique, puisque tu demandes un passage à valeur à catch.
Si par contre tu écris

catch (exception const& e)

tu as vraisemblablement une copie de moins.


Tout à fait.

--
Alain

Avatar
Jean-Marc Bourguet
Stephane Wirtel writes:

Sauf que le compilateur a le droit de fusionner des instances.
Donc, formellement, dans une instruction comme :

throw MonException() ;

le compilateur évalue l'expression, qui donne un temporaire de
type MonException, puis copie cette valeur où il veut, et enfin
appelle le destructeur du temporaire. Mais le compilateur peut
aussi simplement évaluer l'expression directement où il faut, en
supprimant la copie et la destruction. (Même s'il effectue cette
optimisation, en revanche, il faut que la copie soit légale.)

Si l'exception est prise par référence, il se peut bien que le
constructeur de copie ne soit jamais appelé.
James,


C'est effectivement cette 'exception' à la règle qui fait
en sorte que je me demandais si cela pouvait être
désactivable dans la configuration du compilateur.


Il est possible qu'un compilateur donné puisse la désactivé,
mais, d'une part, je ne me souviens pas d'un avoir vu un où
c'était possible, d'autre part, je ne vois pas l'intérêt et
un programme qui dépend de l'exécution du constructeur de
copie à ce moment me semble avoir un problème de fond plus
important que simplement l'oubli d'une règle du C++. Au
fait, la suppression de paire constructeur de
copie/destructeur "inutiles" est possible à d'autres
endroits (par exemple pour le retour d'une fonction ou lors
de la définition de variables).

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


Avatar
Yoxoman
Michel Decima :

Je crois que c'est moi, et j'ai retrouvé le lien:
http://www.codesourcery.com/cxx-abi/abi-eh.htm


Presque.

http://www.codesourcery.com/cxx-abi/abi-eh.html

Il manquait juste le 'l'.

Avatar
Michel Decima
Michel Decima :

Je crois que c'est moi, et j'ai retrouvé le lien:
http://www.codesourcery.com/cxx-abi/abi-eh.htm


Presque.

http://www.codesourcery.com/cxx-abi/abi-eh.html

Il manquait juste le 'l'.


Arf. mauvaise selection lors du copier-coller.


1 2