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

Langage C++ Discussion :

Questions de base sur les exceptions


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Par défaut Questions de base sur les exceptions
    Bonjour.

    Je découvre en ce moment la gestion des erreurs en C++ et j'ai quelques petites questions. Je suis en train de faire une classe pour lire/écrire un type de fichier binaires perso, et j'aimerai bien gérer les erreurs proprement quand il y a un problème de lecture/écriture.

    Aussi j'ai quelques petites question :
    1) Y-a-t-il une erreur standard déjà prête pour les erreurs d'IO ?
    2) Comment faire pour que le code crashe si jamais il y a eu une erreur d'IO ?
    3) Que se passe-t-il si une erreur lancée par un throw() n'est jamais rattrapée par un catch() ?
    4) Peut-on faire des throw() sans bloc try(), et si oui, dans quel contexte ?

    Et plus spécifiquement :
    Actuellement, toutes les fonctions de ma classe retournent une variable "bool ok" pour indiquer que l'opération d'IO s'est bien passée. Si je veux que le code crashe "proprement" si jamais l'opération d'IO s'est mal passée que dois-je rajouter dans mes fonctions avant le "return ok;" ?

    Merci beaucoup

  2. #2
    Membre expérimenté Avatar de Rewpparo
    Homme Profil pro
    Amateur
    Inscrit en
    Décembre 2005
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Amateur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 170
    Par défaut
    Citation Envoyé par Kaluza Voir le message
    1) Y-a-t-il une erreur standard déjà prête pour les erreurs d'IO ?
    les exceptions standard sont dans stdexcept. Choisis en une, ou alors dérives en toi même une nouvelle de exception
    Citation Envoyé par Kaluza Voir le message
    2) Comment faire pour que le code crashe si jamais il y a eu une erreur d'IO ?
    3) Que se passe-t-il si une erreur lancée par un throw() n'est jamais rattrapée par un catch() ?
    4) Peut-on faire des throw() sans bloc try(), et si oui, dans quel contexte ?
    Faire "crasher" ton code c'est simple : *((int*)(0))++; Mais je suppose que c'est pas le but, ce que tu veux, c'est que ton programme se termine, si possible proprement, et si possible avec un message d'erreur.
    Pour ca il suffit de lancer une exception, et de ne jamais la rattraper dans un catch qui va bien (ou même sans bloc try). L'exception "sortira" alors de main, et le programme se terminera.
    Lancer une exception sans try, ou lancer une exception sans un catch approprié ont le même effet, et c'est tout a fait possible (testé par un sagouin des exceptions !). Tu as a lors un joli message d'erreur dans la console (sous linux au moins) avec le message de l'exception.

    Citation Envoyé par Kaluza Voir le message
    Et plus spécifiquement :
    Actuellement, toutes les fonctions de ma classe retournent une variable "bool ok" pour indiquer que l'opération d'IO s'est bien passée. Si je veux que le code crashe "proprement" si jamais l'opération d'IO s'est mal passée que dois-je rajouter dans mes fonctions avant le "return ok;" ?
    Quand une exception est lancée, elle descend le stack proprement, c'est a dire en appelant les destructeurs de toutes les variables sur le stack au fur et a mesure qu'elle descend. Tu peux utiliser ca pour essayer de fermer ton programme le plus proprement possible.
    Sinon les OS de nos jours desalouent automatiquement la mémoire quand le programme quitte, donc si tu veux fermer ton programme, faire ca proprement n'est a priori pas important.
    Par contre, pour les accès à une ressource matérielle (tu nous parles d'IO), ca peut valoir le coup de fermer proprement les interfaces d'accès.

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Kaluza Voir le message
    Bonjour.

    Je découvre en ce moment la gestion des erreurs en C++ et j'ai quelques petites questions. Je suis en train de faire une classe pour lire/écrire un type de fichier binaires perso, et j'aimerai bien gérer les erreurs proprement quand il y a un problème de lecture/écriture.

    Aussi j'ai quelques petites question :
    1) Y-a-t-il une erreur standard déjà prête pour les erreurs d'IO ?
    Non, mais tu peux dériver directement de std::runtime_error pour les erreur de lecture ou de std::invalid_argument si le fichier que tu essaye d'ouvrir n'existe pas
    2) Comment faire pour que le code crashe si jamais il y a eu une erreur d'IO ?
    La solution crade : tu ne place aucun try catch dans ton code... Si on sort de main sans avoir récupéré une erreur, le programme plante en disant qu'il y a une exception qui n'est pas gérée

    La solution propre consiste à faire en sorte de correctement nettoyer le tout dans un try(...) (qui va récupérer toutes les exceptions qui n'ont pas été récupérée par d'autres blocs catch), d'afficher éventuellement un message d'erreur, de veiller à libérer toutes les ressources et de quitter (avec un exit(1) )
    3) Que se passe-t-il si une erreur lancée par un throw() n'est jamais rattrapée par un catch() ?
    Le programme "plante", tout simplement, et tout brutalement
    4) Peut-on faire des throw() sans bloc try(), et si oui, dans quel contexte ?
    Ce n'est pas vraiment conseillé (l'idéal étant qu'il y ait au minimum un try{} catch(...) dans la fonction main pour faire ce que j'ai dit plus haut), car, autrement, le programme plante durement, sans donner la chance de faire quoi que ce soit

    Et plus spécifiquement :
    Actuellement, toutes les fonctions de ma classe retournent une variable "bool ok" pour indiquer que l'opération d'IO s'est bien passée. Si je veux que le code crashe "proprement" si jamais l'opération d'IO s'est mal passée que dois-je rajouter dans mes fonctions avant le "return ok;" ?
    Cela peut dépendre énormément de ce que tu veux faire...

    Typiquement, une erreur transporte avec elle le contexte dans lequel elle est survenue, de manière à donner l'occasion d'y remédier "par ailleurs".

    Selon l'endroit où le contexte est le plus favorable (comprends : selon l'endroit où tu disposeras des informations susceptibles de te donner un indice quant à la manière de résoudre ton erreur), tu peux soit carrément lancer une exception avant le return, soit attendre de récupérer la valeur (false) renvoyée par ta fonction avant de lancer l'exception...

    Le tout étant toujours de savoir si tu as la possibilité de remédier à ton erreur (et les informations qui te permettront de le faire)...

    Un simple exemple:

    Si tu essaye d'ouvrir ton fichier, mais que le nom (transmis en paramètre) est "fichier.bin", et que le vrai nom de fichier doit etre "fichier.bat", tu peux lancer ton exception directement et faire en sorte qu'elle contienne une information du genre de "impossible d'ouvrir le fichier "fichier.bin".

    Ce sera alors à l'utilisateur de fournir le nom de fichier correct.

    Si, par contre, tu obtiens une erreur au moment de lire une donnée, tu peux décider de lancer l'exception au moment meme, mais tu peux aussi attendre d'être revenu dans la fonction qui a appelé celle qui provoque l'erreur pour fournir l'information de ce qui avait déjà été lu avant que cela ne foire
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre éclairé
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Par défaut
    Merci beaucoup pour vos réponses très claires
    J'ai aussi fait quelques tests entre temps et j'ai mieux compris comment cela fonctionnait.

    Je pense que ma classe va juste lancer des exceptions si jamais ça se passe mal, charge à celui qui l'utilise de faire des try/catch. C'est une classe pour lire/écrire des fichiers fortran binaires, pour jongler avec l'endianness et autres joyeusetés donc si jamais un truc semble louche dans le fichier, je pense faire juste un throw et laisser les classes de plus haut niveau se débrouiller avec.

    Merci encore

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Kaluza Voir le message
    pour jongler avec l'endianness et autres joyeusetés donc si jamais un truc semble louche dans le fichier, je pense faire juste un throw et laisser les classes de plus haut niveau se débrouiller avec.

    Merci encore
    C'est, effectivement, la manière dont cela se passe généralement: on lance l'exception à l'endroit où elle se produit, mais la gestion de cette exception se fait généralement plus "haut" dans le programme
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. question de base sur les transactions
    Par nouraty dans le forum Débuter
    Réponses: 3
    Dernier message: 22/12/2010, 21h51
  2. question de base sur les pointeurs
    Par Ganondorf dans le forum Débuter
    Réponses: 4
    Dernier message: 26/08/2010, 17h07
  3. question de base sur les classes
    Par tanguy.L dans le forum Langage
    Réponses: 10
    Dernier message: 28/02/2008, 17h37
  4. Réponses: 13
    Dernier message: 10/10/2007, 10h09
  5. Question de base sur les classes
    Par deaven dans le forum C++
    Réponses: 3
    Dernier message: 27/11/2005, 16h20

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