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 :

Besoin d'aide avec try catch


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 54
    Par défaut Besoin d'aide avec try catch
    Bonjour,
    Dans un programme simple en C++ sous Linux compilé avec g++ je voudrais me servir de try catch pour intercepter les exceptions.

    Ce que je ne comprends pas c'est qu'en faisant un programme de test comme celui ci-dessous mes exceptions ne sont pas catchéés.
    Je viens du monde Delphi ou ce genre d'exceptions seraient bien catcher. Y a t'il une différence en C++ ?
    Merci

    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
    #include <iostream>
    #include <stdexcept>
     
    int main(int argc, char **argv) {
       int i;
       try {
          i =0;
          i = 4/i;
          }
       catch (const std::exception & e) {
          std::cout << "Exception 1: "<< e.what()<<"\n";
          }
       catch (...) {
          std::cout << "Exception 2\n";
          }
    }
    La mon programme plante avec "Floating Point Exception" pourquoi n'est pas intercepté ?

  2. #2
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Car Floating Point Exception est une interruption (c'est un signal envoyé par le processeur). try catch ne fonctionne qu'avec des exceptions lancées par throw et ne fonctionne pas avec des interruptions (des signaux).

  3. #3
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    En clair, il faut que tu crées une classe DivisionParZero qui lance une exception pour que ça marche.

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 54
    Par défaut
    OK Merci c'est ce que j'étais en train de me dire à force de chercher. C'est dommage en Delphi c'est simple les exceptions et les interuptions sont catchés

    Donc si j'ai bien compris j'oublie les division par zéro, les dépassesement de capacités pour les tableaux etc...
    Sinon pour intercepter les interruptions ya pas plus simple que de ce creer une classe a chaque fois ?

  5. #5
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Pour les dépassements de capacités pour les tableaux, je te conseille d'utiliser std::vector avec des itérateurs. Maintenant, si ton programme nécessite forcement d'utiliser des try/catch pour tester ça... c'est que le code n'est vraiment pas bon.

    En clair, il faut que tu crées une classe DivisionParZero qui lance une exception pour que ça marche.
    Oui, et comment tu l'as fait la lancer d'exception ?

    Sachant qu'une exception dans un handler sur le signal, ça ne marche pas :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #include <iostream>
    #include <stdexcept>
    #include <csignal>
     
    class FloatingPointException : public std::exception
    {
      public:
        FloatingPointException()
        {
          msg = "FloatingPointException";
        }
     
        virtual ~FloatingPointException() throw()
        {
        }
     
        virtual const char * what() const throw()
        {
          return this->msg.c_str();
        }
     
      private:
        std::string msg;
    };
     
    void floatingPointExceptionHandler(int i)
    {
      std::cerr<<"floatingPointExceptionHandler"<<std::endl;
      throw FloatingPointException();
    }
     
    void f()
    {
      try
      {
        int i = 0;
        i = 4/i;
      }
      catch(FloatingPointException & e)
      {
        std::cerr<<e.what()<<"e"<<std::endl;
      }
    }
     
    int main()
    {
      signal(SIGFPE, floatingPointExceptionHandler);
      f();
      return 0;
    }

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Lancer des exceptions dans un gestionnaire de signaux est un comportement indéfini.

  7. #7
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Citation Envoyé par loufoque
    Lancer des exceptions dans un gestionnaire de signaux est un comportement indéfini.
    C'est pour ça que je donnais le code pour montrer que ça marchait pas (bon, j'aurais dû préciser que ça aurait pu marcher )

  8. #8
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par millie
    Oui, et comment tu l'as fait la lancer d'exception ?
    ???

    voir http://c.developpez.com/faq/cpp/inde...ONS_type_perso

    On peut tout à fait définir notre propre type d'exception !

  9. #9
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Tu n'as pas compris le soucis. Le problème n'étant pas de définir l'exception, mais de définir comment la lancer.
    Il cherche à intercepter une interruption du type Float Point Exception (SIGFPE). Il est possible de détecter ce signal (SIGFPE) qu'en utilisant un gestionnaire de signaux (avec la fonction signal). Le problème étant qu'une lancée d'exception (comme l'a indiqué loufoque) dans le handler est un comportement indeterminée.

    Tu peux essayer le code que j'ai posté et ne fonctionne pas sur ma machine (x86/windows XP). Il n'est donc pas possible (a priori) de lancer automatiquement une exception et de pouvoir la rattraper pour détecter une interruption.

  10. #10
    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 : 50
    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
    Par défaut
    Pour info, le code initial fourni l'affichage souhaité compilé avec visual C++ et les bonnes options de compilation. Mais ça n'a rien de standard, et c'est uniquement du à la façon dont sont implémentées les exceptions C++ à base de SEH exceptions sous windows/visual C++. Mais en tout cas, ça prouve que ce genre de choses n'est pas impossible à obtenir, à condition de pouvoir modifier son OS/compilateur.
    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.

  11. #11
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par millie
    Tu n'as pas compris le soucis. Le problème n'étant pas de définir l'exception, mais de définir comment la lancer.
    OK !
    Avec un throw!
    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
     
    class DivisionParZero: public std::exception
    {
      virtual const char* what() const throw()
       {
        return "Erreur : tentative de division par zéro";
      }
    } 
     
    int main ()
    {
        try {
            int i = 0;
     
            if (i == 0) throw DivisionParZero();
            int a = 4 / i;
        }
     
        catch (const std::exception & e)
        {
             std::cerr << e.what() ;
        }
    }
    Code non testé, mais c'est l'idée...

  12. #12
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Par défaut
    Vu comme ça, c'est évident mais ce n'était pas ce que LeBigornot voulait.

    Il cherchait à utiliser un code du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int i;
       try {
          i =0;
          //pas de throw à ce moment
          i = 4/i; //la division par 0 lance une exception
          }
       catch (const std::exception & e) {
          std::cout << "Exception 1: "<< e.what()<<"\n";
          }
    De telle manière que l'interruption SIGFPE soit intercepté. Mais ce n'est pas possible de le faire avec des exceptions.


    Regarde mon code que j'ai mis (le deuxième post), on utilise signal pour intercepter SIGFPE, mais ça ne marche pas car comme on l'a dit, la lançée d'exception dans un handler (exécuté suite au lancement du signal SIGFPE) est un comportement indeterminée.

    Sinon, ne t'inquiètes pas, je sais utiliser des exceptions. Le problème ne venant pas de là, le problème venait du fait qu'il avait confondu interruptions (signaux) et exceptions. Et qu'il n'est pas possible de "convertir" une interruption en exception (du moins de manière portable)

  13. #13
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par millie
    Sinon, ne t'inquiètes pas, je sais utiliser des exceptions. Le problème ne venant pas de là, le problème venait du fait qu'il avait confondu interruptions (signaux) et exceptions. Et qu'il n'est pas possible de "convertir" une interruption en exception (du moins de manière portable)
    Je ne m'inquiètes pas....

    C'est sûr que la lancée d'exception automatique est l'idéal. L'utilisation de bibliothèque (STL, Boost, etc...) permet de ne pas polluer son propre code de throw().

    Je vais peut-être dire une connerie (sûrement même), mais peut-être que quelque chose du genre sera dispo dans la nouvelle norme C++0x (en plus du ramasse miette automatique) ???

Discussions similaires

  1. Besoin d'aide avec Regexp::Assemble
    Par mobscene dans le forum Modules
    Réponses: 5
    Dernier message: 11/04/2007, 12h39
  2. [ASA] J'ai besoin d'aide avec sybase et vb6 svp !!
    Par tibo830 dans le forum SQL Anywhere
    Réponses: 7
    Dernier message: 12/05/2006, 10h09
  3. Besoin d'aide avec TinyXML
    Par Clad3 dans le forum Bibliothèques
    Réponses: 5
    Dernier message: 15/08/2005, 18h20
  4. Réponses: 2
    Dernier message: 29/08/2003, 17h52
  5. Besoin d'aide avec postgresql sous windows NT
    Par Chihuahua dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 18/07/2003, 08h29

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