328 votes

C++ attraper toutes les exceptions

Y a-t-il un équivalent en c++ du

try {
    ...
}
catch (Throwable t) {
    ...
}

Je tente de déboguer un code Java/jni qui appelle des fonctions Windows natives et la machine virtuelle cesse de fonctionner. Le code natif semble fonctionner correctement en test unitaire et semble seulement planter lorsqu'il est appelé via jni. Un mécanisme générique de capture d'exceptions serait extrêmement utile.

1 votes

4 votes

Notez que la plupart des crashes ne sont pas causés par des exceptions en C++. Vous pouvez attraper toutes les exceptions, mais cela ne préviendra pas de nombreux crashes.

0 votes

398voto

Greg D Points 24218
essayer{
    // ...
} attraper (...) {
    // ...
}

attrapera toutes les exceptions en C++, mais cela devrait être considéré comme une mauvaise conception. Vous pouvez utiliser le nouveau mécanisme std::current_exception de c++11, mais si vous n'avez pas la capacité d'utiliser c++11 (systèmes de code hérité nécessitant une réécriture), alors vous n'avez aucun pointeur d'exception nommé à utiliser pour obtenir un message ou un nom. Vous voudrez peut-être ajouter des clauses catch séparées pour les différentes exceptions que vous pouvez attraper, et attraper seulement tout en bas pour enregistrer une exception inattendue. Par exemple :

essayer{
    // ...
} attraper (const std::exception& ex) {
    // ...
} attraper (const std::string& ex) {
    // ...
} attraper (...) {
    // ...
}

78 votes

C'est une bonne pratique de capturer les exceptions par référence constante. Comme dans : catch(std::exception const & ex) { /* ... */ }

6 votes

@coryan, Merci pour le rappel. J'ai passé trop de temps dans le monde de C# dernièrement. :)

16 votes

@coryan: Pourquoi est-il recommandé d'attraper par référence constante ?

181voto

Quelqu'un devrait ajouter que l'on ne peut pas attraper les "crashes" dans le code C++. Ceux-ci ne lancent pas d'exceptions, mais font ce qu'ils veulent. Lorsque vous voyez un programme crasher à cause par exemple d'une référence de pointeur nul, c'est un comportement indéfini. Il n'y a pas d'std::null_pointer_exception. Essayer d'attraper des exceptions ne vous aidera pas dans ce cas.

Juste au cas où quelqu'un lit ce fil de discussion et pense qu'il peut trouver la cause des crashes du programme. Un débogueur comme gdb devrait être utilisé à la place.

4 votes

Eh bien, comme le souligne Shy, c'est possible avec le compilateur VC. Ce n'est pas une bonne idée, mais c'est possible.

7 votes

Oui avec SEH. mais pas avec des techniques standard de c++ saines :) eh bien si vous vous en tenez à Windows, vous pouvez presque tout faire :)

1 votes

Mmm... merci pour ce fragment. J'ai cherché la réponse à la question de pourquoi mes exceptions de pointeur null ne sont pas attrapées !

76voto

Greg Hewgill Points 356191
essayer {
   // ...
} attraper (...) {
   // ...
}

Notez que le ... à l'intérieur du attraper est un vrai ellipsis, c'est-à-dire trois points.

Cependant, comme les exceptions en C++ ne sont pas nécessairement des sous-classes d'une classe de base Exception, il n'y a aucun moyen de voir réellement la variable d'exception qui est lancée lors de l'utilisation de ce constructeur.

25 votes

En C++11 il y a : try { std::string().at(1); // cela génère une std::out_of_range } catch(...) { eptr = std::current_exception(); // capture }

2 votes

@bfontaine: Eh bien oui, mais j'ai dit cela pour distinguer le spécificateur de catch de l'espace réservé de code existant dans un commentaire (// ...), qui n'est évidemment pas une syntaxe en C++.

1 votes

@GregHewgill : oui, c'était juste une remarque typographique mineure.

60voto

Clearer Points 369

Il n'est pas possible (en C++) d'attraper toutes les exceptions de manière portable. Cela est dû au fait que certaines exceptions ne sont pas des exceptions dans un contexte C++. Cela inclut des erreurs telles que la division par zéro et autres. Il est possible d'y bricoler pour obtenir la possibilité de lancer des exceptions lorsque ces erreurs se produisent, mais ce n'est pas facile à faire et certainement pas facile à faire correctement de manière portable.

Si vous voulez attraper toutes les exceptions de la STL, vous pouvez faire

try { ... } catch( const std::exception &e) { ... }

Cela vous permettra d'utiliser e.what(), qui renverra un const char*, ce qui peut vous en dire plus sur l'exception elle-même. C'est la construction qui ressemble le plus à la construction Java que vous avez demandée.

Cela ne vous aidera pas si quelqu'un est assez stupide pour lancer une exception qui n'hérite pas de std::exception.

3 votes

Pourquoi n'est-ce pas dans le haut?

19voto

John D. Cook Points 19036

Vous pouvez utiliser

catch(...)

mais c'est très dangereux. Dans son livre Debugging Windows, John Robbins raconte une histoire de guerre à propos d'un bug vraiment méchant qui était masqué par une commande catch(...). Vous êtes bien mieux d'attraper des exceptions spécifiques. Attrapez tout ce que vous pensez que votre bloc try pourrait raisonnablement lancer, mais laissez le code lancer une exception plus haut si quelque chose d'inattendu se produit.

2 votes

Je viens de repérer quelques utilisations de ceux-ci et j'ai ajouté quelques journaux à cette étape. Ne rien faire avec une exception est définitivement demander des ennuis.

0 votes

Pourquoi des problèmes? Peut-on également enregistrer une sorte de e.what() sur les exceptions capturées dans (...) ?

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