12
votes

C ++ - Trouver le type d'exception par défaut pris par défaut

dire que j'ai: xxx

Il pourrait y avoir des cas vous obtenez une exception et que vous ne savez pas d'où cela vient ou pourquoi - dans une bibliothèque externe sans aucune information de débogage. Existe-t-il un moyen de trouver ce qui a été lancé ou d'obtenir des données qui lui sont associées? Ils sont pourraient faire: xxx

mais je ne saurais jamais si j'attrape ...

Travailler dans MSVC ++ 2008 Si cela compte.


0 commentaires

4 Réponses :


1
votes

Vous ne pouvez pas en standard C ++. Je envisagerais de telles exceptions pour être très exceptionnelle et les gérer en essayant de loger le fait que vous avez eu une mauvaise exception, puis essayez de quitter le programme, pendant que vous le pouvez toujours.

Si vous avez de la chance, vous pourrez peut-être enregistrer des données.


0 commentaires

2
votes

Il n'y a aucun moyen de connaître le type d'exception en C ++ (dans Catch (...) Bloc, je veux dire, de cource)

Vous pouvez simplement espérer que vous savez ce que vous savez exactement externalallibrary :: dosomething (); fait, si vous l'avez écrit ou, comme dans votre cas, vous pourriez sauter, qu'il y a vraiment bien Documentation pour externalischibrary :: Dosomething (); et lisez-le s'il y a telle. Toutes les bonnes bibliothèques ont une documentation détaillée.


4 commentaires

La documentation détaillée des exceptions n'est pas aussi fréquente que la documentation décente des paramètres, dans mon expérience. Mais si c'est comme ça que c'est, je vais devoir tester des possibilités standard ... Qu'en est-il des exceptions du système?


Qu'entendez-vous par «Qu'en est-il des exceptions système?» Je ne sais pas s'ils peuvent être pris dans un programme C ++ :? En outre, la plupart des bibliothèques, j'ai utilisées, ont leur propre hiérarchie d'exception bien documentée. Mais, bien sûr, cela ne veut pas dire que toutes les bibliothèques ont une telle chose. En outre, si c'est C lib, vous savez que aucune exception n'est lancée.


Je voulais dire, n'y a-t-il pas de façons spéciaux d'attraper des choses comme l'accès NULL-PTR, DIV / 0 et ainsi de suite? Je pensais qu'il y avait des moyens d'attraper de tels problèmes où la tige de la 3 libère est buggy?


Je ne sais vraiment pas. Ce serait vraiment sympa s'il y a de cette façon :)



6
votes

Étant donné que C ++ est typée de manière statique, vous devez attraper un type connu. Cependant, vous pouvez appeler une fonction externe (ou un ensemble de fonctions) qui gérent des types d'exception inconnus au point que vous appelez. Si ces manipulateurs ont tous des types connus, vous pouvez les enregistrer pour être essayé de manière dynamique.

typedef std::string Extract();
std::vector<Extract*> chain (1, &extract_from_unknown_external_exception);
// Chain would normally be initialized using whatever scheme you prefer for
// initializing global objects.
// A list or other container (including a manual linked list that doesn't
// require dynamic allocation) may be more appropriate, depending on how you
// want to register and unregister handlers.
std::string process_chain() {
  for (std::vector<Extract*>::iterator x = chain.begin(); x != chain.end(); ++x) {
    try {
      return (*x)();
    }
    catch (...) {}  // That handler couldn't handle it.  Proceed to next.
  }
  throw;  // None could handle it, rethrow original exception.
}

void example() {
  try { throws(); }
  catch (...) {
    try {
      std::string extracted = process_chain();
      std::cout << "extracted: " << extracted << '\n';
    }
    catch (...) {
      throw;  // Rethrow unknown exception, or otherwise handle it.
    }
  }
}


2 commentaires

Bonjour, je pense que c'est une bonne réponse. Cependant, je ne trouve aucune information dans la norme quant à savoir s'il s'agit ou non de comportement standard. Je l'ai testé et cela fonctionne à la fois à VisualStudio, GCC et LLVM, mais je ne suis pas tout à fait sûr pourquoi. Donc, entrer dans un nouveau try {} catch () {} bloquer n'affecte aucune exception en cours? Merci!


Je suppose que je ne suis pas non plus sûr de savoir pourquoi ça ne marcherait pas. Il semble avoir un sens pour moi que l'entrée dans un bloc d'essai n'aurait aucune incidence sur les exceptions actuelles, mais je suppose que je veux juste vérifier.



18
votes

Si vous utilisez GCC ou Clang, vous pouvez utiliser un truc pour connaître le type d'exception 'inconnu'. N'oubliez pas que cela est non standard!

#include <cstdlib>
#include <iostream>
#include <cxxabi.h>


using namespace __cxxabiv1;

std::string util_demangle(std::string to_demangle)
{
    int status = 0;
    char * buff = __cxxabiv1::__cxa_demangle(to_demangle.c_str(), NULL, NULL, &status);
    std::string demangled = buff;
    std::free(buff);
    return demangled;
}

struct MyCustomClass
{};

int main(int argc, char * argv[])
{
    try
    {
        throw MyCustomClass();
    }
    catch(...)
    {
        std::cout << "\nUnknown exception type: '" << util_demangle(__cxa_current_exception_type()->name()) << "'" << std::endl;
    }
    return(0);
}


0 commentaires