53 votes

Pourquoi les flux iostreams C ++ STL ne sont-ils pas "exceptionnels"?

Je suis habitué à la VCL Delphi Cadre, où TStreams lancer des exceptions en cas d'erreur (e.g de fichier n'est pas trouvé, le disque est plein). Je suis le portage d'un code pour l'utilisation de C++ STL au lieu de cela, et ont été capturés par iostreams de ne PAS jeter des exceptions par défaut, mais la mise en badbit/failbit n'drapeaux à la place.

Deux questions...

a: Pourquoi est-ce - qu'Il semble étrange de décision de conception pour une langue construite avec des exceptions en elle dès le premier jour?

b: la meilleure Façon d'éviter cela? J'ai pu produire cale de classes qui se jettent comme je l'espère, mais cela se sent comme à réinventer la roue. Peut-être il y a une bibliothèque BOOST qui fait cela dans un saner de la mode?

76voto

KennyTM Points 232647

un. C++ n'est pas construit avec des exceptions, dès le premier jour. "C with classes" a commencé en 1979, et des exceptions ont été ajoutées en 1989. Pendant ce temps, l' streams bibliothèque a été écrite dès 1984 (devient plus tard iostreams en 1989 (plus tard ré-implémenté par GNU en 1991)), il ne peut pas utiliser la gestion des exceptions dans le début.

Ref:

b. Vous pouvez activer les exceptions à l' .exceptions méthode.

// ios::exceptions
#include <iostream>
#include <fstream>
#include <string>

int main () {
  std::ifstream file;
  file.exceptions ( ifstream::failbit | ifstream::badbit );
  try {
    file.open ("test.txt");
    std::string buf;
    while (std::getline(file, buf))
      std::cout << "Read> " << buf << "\n";
  }
  catch (ifstream::failure e) {
    std::cout << "Exception opening/reading file\n";
  }
  std::cout.flush();

  file.close();

  return 0;
}

5voto

Roddy Points 32503

OK, c'est "la Réponse à ma propre question" le temps...

Tout d'abord, merci à KennyTM pour l'histoire. Comme il le dit, C++ était PAS conçu avec des exceptions dès le premier jour, il est donc pas surprenant de constater que iostreams 'exception de la gestion a été boulonné par la suite.

Deuxièmement, comme Neil B souligne, avoir des exceptions sur le format d'entrée des erreurs de conversion serait une douleur importante. Cela m'a surpris, parce que je considérais iostreams comme un simple système de fichiers wrapper couche, et je n'avais pas envisagé ce cas à tous.

En troisième lieu, il apparaît BOOST apporte quelque chose à la fête: coup de pouce.IOStreams. Si je comprends bien, ces manipuler le faible niveau des I/O et de mise en mémoire tampon aspect de cours d'eau, laissant le régulier c++ IOStreams bibliothèque pour gérer les problèmes de conversion. Coup de pouce.IOStreams fait l'utilisation des exceptions dans la façon dont je m'attends. Si je comprends bien, Kenny exemple pourrait aussi ressembler à ceci:

#include <ostream>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/stream.hpp>

int main () {
  boost::iostreams::stream_buffer <boost::iostreams::file_source> buf("test.txt");
  std::istream file(&buf);

  try {
    std::string buf;
    while (std::getline(file, buf))
      std::cout << "Read> " << buf << "\n";
  }
  catch (std::ios_base::failure::failure e) {
    std::cout << "Exception opening/reading file\n";
  }
  std::cout.flush();

  file.close();

  return 0;
}

Je pense que avec cette version, des choses comme "fichier non trouvé" doivent jeter, mais "istream' erreurs seront signalées par badbit/failbit n'.

3voto

Neel Basu Points 4371
  1. Chaque fois que vous lancez une exception, vous devez penser à la sécurité des exceptions. donc aucune exception aucune exception aucune exception maux de tête de sécurité.

  2. STL fournit également des exceptions, mais la levée d'exception est facultative. vous pouvez activer l'exception en définissant exceptions (failbit | badbit | eofbit)

  3. STL vous permet d'avoir un comportement sans exception ni attente.

0voto

Steve314 Points 12599

Mon avis est que les exceptions ne doivent pas être utilisés pour toutes les erreurs, et ne doit pas nécessairement être réservés pour la gestion des erreurs. Le plus simple ligne directrice est que les exceptions sont pour le traitement des cas exceptionnels, où la manipulation de la condition autrement fait un gâchis de la code avec des tas de sortie-ce l'échec des tests.

En e/S normale de manutention, des choses comme des expressions du folklore ne sont pas vraiment exceptionnelles, elles sont attendues, et normalement plus proprement gérée à l'aide de non-exception méthodes. De même, lors de la recherche d'un conteneur, l'incapacité à trouver la clé particulier n'est pas nécessairement imprévues ou exceptionnelles, il est donc approprié pour par exemple std::find pour revenir à la fin-lié-de-gamme de la valeur pour "échec".

D'autre part, alors que beaucoup ne seront pas d'accord, je crois qu'il est approprié d'utiliser une exception pour la réussite d'une recherche récursive. Par appel, l'échec est le cas normal - et à l'aide d'une exception pour le succès peut nettoyer la structure de la fonction récursive considérablement. Alors que je ne suis pas sûr que je voudrais l'utiliser dans le monde réel, en levant une exception pour les réduire et de retour que pour aucune correspondance n'est trouvée donne une assez propre et facile à suivre mandature LR analyseur.

BTW - je n'aime pas compter sur iostream pour la saisie de toute façon, sauf dans un simple donnez-moi-le-tout-fichier-le contenu (ou une taille fixe de bloquer à un moment) façon. Je trouve plus simple et plus robuste à utiliser d'autres méthodes pour valider et interpréter une entrée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X