Will C à deux pas de travail sans arguments dans un autre cadre pour réémettre une exception?

StackOverflow https://stackoverflow.com/questions/3561571

  •  01-10-2019
  •  | 
  •  

Question

Si j'ai un code comme suit:

try {
  doSomething();
} catch (...) {
  noteError();
}

void noteError() {
  try {
    throw;
  } catch (std::exception &err) {
    std::cerr << "Note known error here: " << err.what();
  } catch (...) {
    std::cerr << "Note unknown error here.";
  }
  throw;
}

Est-ce que les exceptions sont jetés d'origine des deux endroits à l'intérieur du cadre inférieur de noteError ()?

Était-ce utile?

La solution

Le libellé de la norme (§ 15.1 / 2) est (Souligné par l'auteur):

  

Si une exception est levée, la commande est transférée à la gestionnaire le plus proche avec un type d'appariement (15,3); « Les plus proches » désigne le gestionnaire pour lequel le composé déclaration, cteur-initialiseur, ou la fonction du corps après le mot clé try a été le plus récemment entré par le fil de contrôle et pas encore sorti.

Quand a un bloc try "sorti"? Selon la grammaire (§15 / 1), blocs try se terminent par un Séquence de gestionnaires, de sorte que les extrémités de bloc lorsque les dernières extrémités de gestionnaire. En d'autres termes:

try // <- start of try block
{
}
catch (whatever) // <- first handler
{
}
// ... more handlers
catch (whatever_again) // <- last handler
{
} // <- end of try block

Alors oui, votre code est très bien. Lorsque jeté re, le bloc d'essai le plus proche est un gestionnaire correspondant (à savoir de catch (...)), de sorte que gestionnaire est entré.

Autres conseils

Votre code d'origine était très bien. Vous avez attrapé différents types d'exception et a appelé une fonction qui enregistre un message et réémettre. La déclaration de throw n'est pas tenu de se présenter directement à l'intérieur du bloc de catch correspondant. Si vous appelez une de ces fonctions « note » et vous êtes pas manutention actuellement une exception, cependant, votre programme appellerez terminate().

Votre nouveau code est aussi très bien. Il est OK pour tout attraper, puis appeler une autre fonction qui rethrows pour aller à un gestionnaire plus spécifique. C'est l'idiome dispatcher exception décrit dans le C ++ FAQ . Il semble un peu particulier à réémettre l'exception après le bloc de répartition est terminée, mais si cette même déclaration de throw avait eu lieu après noteError retourné (à l'intérieur du bloc catch d'origine) au lieu de là où il est maintenant, il serait tout à fait ordinaire; il est démontré dans la norme, § 15.1 / 6.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top