11
votes

Pourquoi mes exceptions de C ++ ne sont-elles pas attrapées?

J'ai un code C ++ qui utilise un modèle d'exception très standard:

try {
  // some code that throws a std::exception
}
catch (std::exception &e) {
  // handle the exception
}


2 commentaires

Quelles preuves devez-vous vous faire penser qu'une exception est lancée? Quelles preuves avez-vous que cela dérive de std :: exception ? (Ne pas dire que vous avez tort, mais il y a un manque distinct d'informations ici)


Pour que quiconque trouve cela à partir de la recherche, cochez également (a) Cet autre thread et (b) que votre jette n'est pas enterré dans les appels de fonction imbriqués, dont les appels extérieurs ont moins de spécifications d'exception permissives, y compris noexcept . Si la fonction de lancement est spécifiée correctement mais elle s'appelle par une fonction noexcept (ou une fonction qui ne jette pas la chose qui est lancée), l'appelant se terminera. Cela pourrait être basique, mais cela me coûte juste quelques minutes de grattage de la tête, alors!


8 Réponses :


16
votes

Essayez un Catch (...) {} bloc, voir si une exception est vraiment lancée.


2 commentaires

Je ne comprends pas cette réponse - la question inclut déjà un bloc de capture ().


La question inclut un gestionnaire pour des exceptions de type std :: exception . Un bloc de capture utilisant une ellipsis (...) car le paramètre des captures attrapera toute exception, quel que soit le type de l'exception de lancer. Beaucoup comme un gestionnaire "par défaut".



4
votes

Je peux offrir deux théories:

  1. L'exception se fait prendre avant de viendra votre clause de capture; Toute fonction sur la pile pourrait être le coupable. Comme Michael propose, essayez de tout attraper.
  2. La déruisement d'exception échoue pour localiser votre gestionnaire. Pour analyser cela plus en détail, vous devrez passer à travers le code de déroulement d'exception, qui est très velu. Voir si la compilation du code de l'objectif-c avec -fobjc-exceptions aide.

0 commentaires

1
votes

Ceci pourrait être un coup long, mais dans les paramètres de compilateur Visual Studio, il est possible d'éteindre entièrement des exceptions. Peut-être qu'il y a quelque chose de similaire dans GCC / XCode.


0 commentaires

0
votes

C ++ Les exceptions peuvent être à peu près n'importe quoi, assez souvent un char * . Comme suggéré avant d'ajouter attraper (...) pour le faire briser et voir ce qui se passe.


1 commentaires

Je n'ai jamais vu un Char * exception et giflerait quiconque utilisé un



7
votes

Je soupçonne que l'interaction entre Objective-C et C ++ est le coupable, mais toutes mes tentatives de la broyeur ont échoué.

Vous avez probablement raison, même s'il est difficile de suivre.

Premier, GCC explicitement Ne vous permet pas de lancer des exceptions dans l'objectif C ++ et de les attraper en C ++ ("lorsqu'il est utilisé chez Objective-C ++, le modèle d'exception Objective-C n'interope pas avec des exceptions C ++ à ce stade. Cela signifie que vous ne pouvez pas @throw une exception de l'objectif-C et attrape en C ++ ou vice versa (c.-à-d. lancer ... @catch ). ")

Cependant, je pense que vous décrivez un cas où l'objectif C ++ appelle C ++ Code, le code C ++ jette et que vous espérez que le code C ++ pour attraper l'exception. Malheureusement, j'ai des difficultés à trouver de la documentation pour ce cas particulier. Il y a de l'espoir car, " C'est CONSIDÉRÉ SOIGNÉ POUR JOUER UNE EXCEPTION C ++ d'un fichier via un autre fichier compilé pour le modèle d'exception Java, ou inversement, mais il peut y avoir des bogues dans cette zone . " S'ils peuvent le faire pour Java, il est possible qu'ils puissent le faire pour l'objectif C ++.

À tout le moins, vous devrez spécifier -fexceptions au moment de la compilation (" Vous devrez peut-être activer cette option lors de la compilation du code C qui doit interagir correctement avec des gestionnaires d'exceptions écrites en C ++ " ). Encore une fois, cela ne mentionne pas spécifiquement l'objectif c ++ mais il peut s'appliquer.


0 commentaires

6
votes

Un petit peu connu Gotcha avec des exceptions concerne l'accès de la classe de base.

Si vous lancez une classe qui dérive en privé de std :: exception code> alors le STD: : exception code> le gestionnaire ne sera pas choisi. p>

Par exemple: P>

#include <iostream>

class A { };
class B : private A { } ;

int main ()
{
  try
  {
    throw B ();
  }
  catch (A & )
  {
    std::cout << "Caught an 'A'" << std::endl;
  }
  catch (B & )
  {
    std::cout << "Caught an 'B'" << std::endl;
  }
}


0 commentaires

18
votes

C ++ vous permet une variété d'options pour attraper: valeur, valeur, référence ou pointeur. Notez que ce code attrape uniquement STD :: Exceptions passées par référence ou valeur:

catch (std::exception* e)


7 commentaires

Merci, cela vient de fixer mon problème.


Cette réponse a été une excellente trouvaille, venant de Java / Scripting Langues Contexte On suppose naturellement que des exceptions sont toujours transmises par la valeur. THX.


Désolé mais cette réponse est fausse. Vous pouvez prendre une exception par valeur ou référence, mais c'est toujours jeté par valeur - soit attrape fonctionnera correctement. La capture par référence est préférée pour empêcher la découpage d'objet d'exception. Lancer un pointeur est une chose toutale différente, car std :: exception * est un type complètement différent de std :: exception .


@MarkRansom - Merci d'avoir attrapé cette erreur. J'ai mis à jour ma réponse pour supprimer le texte se référant à lancer par référence. Je ne suis pas sûr de ce que je pensais ce jour-là.


@Benl: Je hautement ne recommande pas de ne pas jeter par le pointeur. Jeter par la valeur et attraper la référence de const.


YEP sonne comme un programmeur Java est entré en C ++ et a commencé à écrire lancer une nouvelle exceptiontype (..) tsk! Dans ce cas, l'objet d'exception est un pointeur, et c'est "attrapé par la valeur"; Il arrive simplement à être celui qui pointe une instance d'une classe conçue pour être utilisée pour des objets d'exception


Voir Related jeter neuf std :: exception vs the sdd :: exception .



-2
votes

Merci pour la contribution de tout le monde. Ce sont de bonnes suggestions pour quiconque rencontre un problème similaire. Cela fonctionne maintenant, mais je ne suis pas sûr à 100%, lequel de divers changements que j'ai faits a fait que les choses deviennent sans faute d'esprit. Encore une fois, l'approche de la simplification de quelque chose qui fonctionne et de la construction de là a payé.

Une chose qui n'a pas été mentionnée dans les réponses et que je pense faisait partie de ma confusion, est de s'assurer que le gestionnaire le rend évident qu'il a effectivement attrapé l'exception. Je pense que dans certaines de mes formulations du gestionnaire, il masquait ce fait et faisait passer l'exception à un gestionnaire de niveau supérieur.


0 commentaires