2009-09-04 15 views
8

que tienen algo de código C++ que utiliza un patrón de excepción muy estándar:¿Por qué no se detectan mis excepciones de C++?

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

El problema es que las excepciones no están siendo atrapados y no pueden entender por qué.

El código se compila en una biblioteca estática en OS X (a través de Xcode). La biblioteca está vinculada a una aplicación Cocoa, con una llamada a la función en cuestión que se produce a través de un procesador de Objectivo-C++. Sospecho que la interacción entre Objective-C y C++ es la culpable, pero todos mis intentos de fijarlo han fallado.

No he podido crear un ejemplo simple que reproduzca este comportamiento en un ejemplo simple. Cuando saco el código relevante del contexto de mi gran programa, todo funciona.

¿Alguien puede sugerir por qué no se detectan mis excepciones?

+1

¿Qué evidencia tienes para hacerte pensar que se está lanzando una excepción? ¿Qué evidencia tienes que deriva de 'std :: exception'? (No digo que estés equivocado, pero hay una clara falta de información aquí) –

Respuesta

-2

Gracias por la contribución de todos. Esas son buenas sugerencias para cualquier persona que se encuentre con un problema similar. Está funcionando ahora, pero no estoy 100% seguro de cuál de los varios cambios que hice hizo que las cosas volvieran a ser sensatas. Una vez más, el enfoque de simplificar a algo que funciona y reconstruir desde allí dio sus frutos.

Una cosa que no se mencionó en las respuestas, y que creo que fue parte de mi confusión, es asegurarme de que el manejador hace obvio que en realidad captó la excepción. Creo que en algunas de mis formulaciones del controlador estaba enmascarando ese hecho y pasando la excepción a un manejador de nivel superior.

15

Pruebe con un bloque catch(...) {}, vea si realmente se produce una excepción.

+0

No entiendo esta respuesta: la pregunta ya incluye un bloque catch(). –

+3

La pregunta incluye un controlador para excepciones de tipo 'std :: exception'. Un bloque catch usando puntos suspensivos (...) ya que el parámetro catch capturará cualquier excepción sin importar el tipo de excepción de throw. Al igual que un controlador "predeterminado". –

3

puedo ofrecer dos teorías:

  1. la excepción queda atrapado antes de que se le presente cláusula catch; cualquier función en la pila podría ser la culpable. Como Michael propone, intenta atrapar todo.
  2. El desenrollado de la excepción no ubica su controlador. Para analizar esto con más detalle, tendría que pasar por el código de desenrollado de excepción, que es muy complicado. Vea si ayuda compilar el código Objective-C con -fobjc-exceptions.
1

Esto podría ser una posibilidad remota, pero en la configuración del compilador de Visual Studio hay una opción para desactivar las excepciones por completo. Quizás hay algo similar en GCC/XCode.

0

Las excepciones de C++ pueden ser casi cualquier cosa, muy a menudo un char*. Como se sugirió antes, agregue catch (...) para al menos hacer que se rompa y ver qué está pasando.

+2

Nunca he visto una excepción 'char *' y abofetearía a cualquiera que haya usado uno –

7

Sospecho que la interacción entre Objective-C y C++ es la culpable, pero todos mis intentos de fijar esto han fallado.

Probablemente tenga razón, aunque es difícil de localizar.

En primer lugar, GCC explícitamente does not allow you to throw exceptions in Objective C++ and catch them in C++ ("cuando se usa de Objective-C++, el modelo de excepciones de Objective-C no interoperar con excepciones de C++ en este momento. Esto significa que puede no @throw una excepción a Objective-C y catch en C++ o viceversa (es decir, throw ... @catch). ")

Sin embargo, creo que usted está describiendo un caso en Objective C++ llama a código C++, el código C++ lanza y que está esperando para el código C++ para atrapa la excepción Desafortunadamente, tengo dificultades para encontrar documentación para este caso específico. Hay alguna esperanza porque, "It is believed to be safe to throw a C++ exception from one file through another file compiled for the Java exception model, or vice versa, but there may be bugs in this area". Si pueden hacerlo para Java, existe la posibilidad de que puedan hacerlo para Objective C++.

Por lo menos, deberá especificar -fexceptions en tiempo de compilación ("es posible que necesite habilitar esta opción al compilar el código C que necesita interoperar adecuadamente con controladores de excepción escritos en C++").Una vez más, eso no menciona específicamente Objective C++, pero puede aplicarse.

5

Un poco conocido de gotcha con excepciones se refiere al acceso de la clase base.

Si en realidad está lanzando una clase derivada privadamente de std::exception, no se elegirá el controlador std::exception.

Por ejemplo: una orden de los manipuladores de resultarían en el controlador de 'B' tal, nunca ser seleccionado

#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; 
    } 
} 

Por lo general, pero en este caso dervies 'B' de 'A' en privado y por lo el controlador de captura para el tipo 'A' no se considera.

16

C++ allows you a variety of options for catching: value, reference or pointer. Tenga en cuenta que este código sólo atrapa std :: excepciones pasados ​​por referencia o valor:

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

Es probable que la excepción se está pasando por el puntero:

catch (std::exception* e) 

Comprobar el código eso es arrojar la excepción y ver cómo lo está haciendo.

Como señala Mark, si captura por valor en lugar de referencia, corre el riesgo de cortar su objeto.

+0

Gracias, esto acaba de solucionar mi problema. –

+0

Me alegra oírlo, Ben L! – Bill

+0

Esta respuesta fue un gran hallazgo, proveniente del origen de los lenguajes de Java/scripting uno asume naturalmente que las excepciones siempre pasan por valor. Gracias. – Cray

Cuestiones relacionadas