IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[FAQ] instruction throw() et redéfinition (dérivation)


Sujet :

C++

  1. #1
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut [FAQ] instruction throw() et redéfinition (dérivation)
    mon compilateur (g++ 3.3.2) n'aime pas la redéfinition d'une fonction membre dans une classe dérivée qui possédait l'instruction throw() dans la classe mère.
    en particulier dans les codes de la FAQ concernant la dérivation de la classe std::exception, il n'accepte pas une classe dérivée sans redéfinition du destructeur et aussi what sans rajouter throw().
    Quelle est donc la solution ?

    PS : je n'ai pas vraiment compris la dernière phrase de la FAQ sur ce sujet
    Comment s'assure-t-on qu'aucune exception ne sera levée ?
    http://c.developpez.com/faq/cpp/?pag...fonction_throw
    " Tout homme est digne d'un parapluie." Stavroguine dans Les Démons de Dostoïevski.

  2. #2
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut Re: [FAQ] instruction throw() et redéfinition (dérivation)
    Citation Envoyé par PINGOUIN_GEANT
    Comment s'assure-t-on qu'aucune exception ne sera levée ?
    http://c.developpez.com/faq/cpp/?pag...fonction_throw


    Justement, throw() ne sert pas à s'assurer que la fonction ne lancera pas d'exception: elle sert juste à indiquer qu'elle n'en lancera pas. Donc il ne faut utiliser throw() que si tu maitrise parfaitement ta fonction et que tu es sur qu'elle n'en lancera pas. Car si elle lance une exception alors que throw() est spécifié, la fonction unexpected est appelée, qui par défaut appelle terminate (=> "Abnormal program termination", méchant ^^).

    A+
    Un historique local pour Visual Studio 2005 et 2008 :
    http://www.codeplex.com/VLH2005

  3. #3
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    OK merci, l'instruction throw() doit donc faire gagner du temps à l'exécution, n'est-ce pas ?
    il me reste plus que le 2° problème.
    " Tout homme est digne d'un parapluie." Stavroguine dans Les Démons de Dostoïevski.

  4. #4
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Non, elle en fait potentiellement perdre.

    En effet, le compilateur doit ajouter du code pour vérifier si une exception est lancée, et dans ce cas, appeler unexpected.

    Beaucoup de gens conseillent de ne pas utiliser les spécifications d'exceptions en C++. En particulier, du fait qu'une analyse statique n'est pas effectuée (à cause entre autre de la compilation séparée), elle n'aportent pas vraiment de sûreté de fonctionnement, et ont un coût.

    Certainnes porpositions en cours visent à introduire une forme d'exception se spécification vérifiable statiquement uniquement pour spécifier qu'une fonction ne peut pas lancer d'exception (ce qui est souvent une chose très utile à savoir pour pouvoir faire du code exception safe).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  5. #5
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par JolyLoic
    Non, elle en fait potentiellement perdre.

    En effet, le compilateur doit ajouter du code pour vérifier si une exception est lancée, et dans ce cas, appeler unexpected.
    Dans le cas du throw(), tu en es sûr ? J'avais lu que certaines libs (la glib je crois) l'utilisaient avec succès pour rendre le code plus performant. Mais c'est vrai que ce que tu dis semble logique.

  6. #6
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    Citation Envoyé par JolyLoic
    Non, elle en fait potentiellement perdre.

    En effet, le compilateur doit ajouter du code pour vérifier si une exception est lancée, et dans ce cas, appeler unexpected.
    Dans le cas du throw(), tu en es sûr ?
    Je ne suis pas un spécialiste des exceptions, mais je ne vois rien qui puisse donner un statut particulier à throw() par rapport à un throw(quelquechosededans).

    Une petite recherche sur le web m'a donné :
    http://www.boost.org/more/lib_guide.htm#Exception-specification
    http://www.gotw.ca/gotw/082.htm

    La fin du code de boost semble dire que dans certains cas particuliers, elle peut effectivement avoir un aspect positif. Personellement, je préfèrerais un truc comme celui décrit dans http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1703.pdf
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  7. #7
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1703.pdf
    In considering the amount of work entailed we should remember that the next release of the C++ Standard will effectively be C++ from 2010 to 2020.
    Ouch, je pensais que c'était prévu plus tôt...

  8. #8
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    je confirme que ce code de la FAQ ne compile pas chez moi avec la version g++ 3.3.3
    http://c.developpez.com/faq/cpp/?pag...ONS_type_perso
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    #include <iostream>
    #include <sstream>
    #include <exception>
     
    class my_exception : public std::exception
    {
    public:
        my_exception( const char * Msg, int Line )
        {
            std::ostringstream oss;
            oss << "Erreur ligne " << Line << " : "
                << Msg;
            this->msg = oss.str();
        }
     
        virtual const char * what() const
        {
            return this->msg.c_str();
        }
     
    private:
        std::string msg;
    };
     
    int main()
    {
        try
        {
            throw my_exception( "exception test", __LINE__ );
        }
        catch ( const std::exception & e )
        {
            std::cerr << e.what() << "\n";
        }
    }
    A propos des spécifiactions d'exceptions, j'au lu dans le Stroustrup que c'était juste pour améliorer la lisibilité au niveau de grosses bibliothèques, comme cela on n'avait pas à regader tout en détails.
    question idiote :
    mais est-ce que mettre le main dans un try et faire un catch (...) puis appliquer std::terminate serait une alternative ?
    on sauve les exceptions qu'on peut et on termine à cause des autres, sans se soucier de fonctions qui ont le droit ou pas d'en lancer.
    Merci à vous.
    " Tout homme est digne d'un parapluie." Stavroguine dans Les Démons de Dostoïevski.

  9. #9
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Citation Envoyé par PINGOUIN_GEANT
    je confirme que ce code de la FAQ ne compile pas chez moi avec la version g++ 3.3.3
    En effet, chez moi non plus avec Dev C++ (g++ 3.3.1).
    Par contre, aucun problème avec C++Builder 6.

    Le code de la FAQ compile bien en faisant ces deux modifs:
    - ajout de throw() lors de la surcharge de what
    - création d'un destructeur ~my_exception() throw() {}

    A+
    Un historique local pour Visual Studio 2005 et 2008 :
    http://www.codeplex.com/VLH2005

  10. #10
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    C'est noté, on va regarder ça...

  11. #11
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Citation Envoyé par PINGOUIN_GEANT
    A propos des spécifiactions d'exceptions, j'au lu dans le Stroustrup que c'était juste pour améliorer la lisibilité au niveau de grosses bibliothèques, comme cela on n'avait pas à regader tot en détails.
    C'est aussi ce que je pensais, mais voici un extrait de code de la bibliothèque boost (boost/smart_ptr/shared_ptr ici):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ...
        reference operator* () const; // never throws
        T * operator-> () const; // never throws
        T * get() const; // never throws
    ...
    => etant donné que "throw()" sert uniquement à indiquer qu'une fonction ne lancera pas d'exceptions, ils utilisent des commentaires, ce qui revient au même pour l'utilisateur.
    Un historique local pour Visual Studio 2005 et 2008 :
    http://www.codeplex.com/VLH2005

  12. #12
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    je me pose d'autres questions sur les exceptions :
    à propos des flux d'entrée et de sortie, apparemment il n'y a pas grand chose niveau standard pour le lancement d'exceptions à part std::clear() qui ne doit pas se lancer souvent. Donc je suppose que la démarche à suivre et de créer soi-même ses classes d'exceptions et de vérifier l'état des flux.
    le petit problème dans la FAQ (ou compilo g++) et les gens qui ne conseillent pas d'utiliser throw() ne changent rien au fait qu'il est toujours conseillé de dériver ses exceptions depuis la classe std::exception
    " Tout homme est digne d'un parapluie." Stavroguine dans Les Démons de Dostoïevski.

  13. #13
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par rolkA
    => etant donné que "throw()" sert uniquement à indiquer qu'une fonction ne lancera pas d'exceptions, ils utilisent des commentaires, ce qui revient au même pour l'utilisateur.
    D'après ce qu'a dit loïc, c'est pas équivalent, car si une fonction throw() lance quand même une exception ça appelle (théoriquement) unexpected() et hop c'est fini. Dans le cas du commentaire, ben elle est lancée et puis tant pis.

  14. #14
    Membre averti
    Avatar de rolkA
    Inscrit en
    Juillet 2003
    Messages
    324
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 324
    Points : 369
    Points
    369
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    Citation Envoyé par rolkA
    => etant donné que "throw()" sert uniquement à indiquer qu'une fonction ne lancera pas d'exceptions, ils utilisent des commentaires, ce qui revient au même pour l'utilisateur.
    D'après ce qu'a dit loïc, c'est pas équivalent, car si une fonction throw() lance quand même une exception ça appelle (théoriquement) unexpected() et hop c'est fini. Dans le cas du commentaire, ben elle est lancée et puis tant pis.
    ... Mais ce cas n'arrive pas, sauf si le programmeur a indiqué throw() alors qu'une exception risque d'être lancée, et c'est une erreur.
    Un historique local pour Visual Studio 2005 et 2008 :
    http://www.codeplex.com/VLH2005

  15. #15
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    Citation Envoyé par Aurelien.Regat-Barrel
    D'après ce qu'a dit loïc, c'est pas équivalent, car si une fonction throw() lance quand même une exception ça appelle (théoriquement) unexpected() et hop c'est fini. Dans le cas du commentaire, ben elle est lancée et puis tant pis.
    en fait c'est Rolka lui-même qui avait fait la remarque.
    par contre, vu les liens de Loïc Joly, il n'est pas étonnant que boost préfère mettre un commentaire plutôt qu'une spécification d'exception.
    je marque le sujet comme résolu, vu qu'on a répondu à ma première interrogation concernant la FAQ mais si qqn a les réponses à mes questions métaphysiques, je suis preneur.
    " Tout homme est digne d'un parapluie." Stavroguine dans Les Démons de Dostoïevski.

  16. #16
    Expert éminent sénior

    Homme Profil pro
    pdg
    Inscrit en
    Juin 2003
    Messages
    5 751
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : pdg

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 751
    Points : 10 670
    Points
    10 670
    Billets dans le blog
    3
    Par défaut Re: [FAQ] instruction throw() et redéfinition (dérivation)
    Citation Envoyé par PINGOUIN_GEANT
    PS : je n'ai pas vraiment compris la dernière phrase de la FAQ sur ce sujet
    Comment s'assure-t-on qu'aucune exception ne sera levée ?
    http://c.developpez.com/faq/cpp/?pag...fonction_throw

    As-tu mieux compris ? Qu'est-ce qui ne va pas dans la formulation ?

  17. #17
    Membre habitué Avatar de PINGOUIN_GEANT
    Profil pro
    Inscrit en
    Juin 2004
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2004
    Messages : 149
    Points : 155
    Points
    155
    Par défaut
    pour ce point, c'est OK. Je te remercie.
    Je faisais allusion à ce que j'avais mis dans les posts après, notamment la gestion des erreurs pour les flux etc...
    " Tout homme est digne d'un parapluie." Stavroguine dans Les Démons de Dostoïevski.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [FORMS] Chemin des icones (intégré FAQ 150 QR)
    Par jerome62 dans le forum Forms
    Réponses: 2
    Dernier message: 30/07/2002, 08h32
  2. [Crystal Report][VB6] instruction PrintReport
    Par yyyeeeaaahhh dans le forum SDK
    Réponses: 4
    Dernier message: 29/07/2002, 14h58
  3. Dérivation dune fonction
    Par srvremi dans le forum C++Builder
    Réponses: 2
    Dernier message: 27/07/2002, 14h21
  4. [TASM] Problème concernant l'instruction LGDT
    Par Ninkosen dans le forum Assembleur
    Réponses: 3
    Dernier message: 15/07/2002, 19h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo