2010-08-12 16 views
5

He oído que lanzar excepciones en/desde una biblioteca C++ podría ser potencialmente peligroso, particularmente con DLL, y particularmente si el código de llamada y la biblioteca están compilados con diferentes compiladores. ¿Hay algo de cierto en esto? ¿Es seguro siempre que me adhiera a las bibliotecas estáticas? Tenga en cuenta que no estoy hablando del uso interno de excepciones en la biblioteca solamente, también quiero profundizar en el código de llamada :)¿No es seguro lanzar excepciones desde librerías C++ enlazadas estáticamente?

Solo para aclarar: Digamos que obtuve una biblioteca estática compilada que define la clase Foo como esto:

class Foo 
{ 
public: 
    // Constructor 
    Foo() 
    { 
     /* ... Do stuff ... */   
     if (stuffwentwrong) 
      throw(123); // We throw an integer error code (to make it simple) 
    } 
}; 

y un tipo lo utiliza como esto:

try 
{ 
    Foo foo_object; 
} 
catch (int i) 
{ 
    std::cout << "Oh bum. Code: " << i; 
} 

sería eso seguro?

+0

Hubo problemas (hace unos 15 años), estos han sido resueltos (a menos que usted está haciendo las cosas cobardes como cargar dinámicamente/descarga DLL por sí mismo). Si simplemente usa directamente una DLL, entonces debería estar bien. –

Respuesta

3

y particularmente si el código de llamada y la biblioteca son recopilados con diferentes compiladores

lo general, no se pueden mezclar distintos compiladores de C++ que no tienen ABI compatible. Por lo tanto, por ejemplo, no puede lanzar una excepción de la biblioteca compilada con MSVC y tratar de detectar con GCC.

Pero, de lo contrario, generalmente no tiene problemas.

pequeña nota:

MSVC tiene varios modelos de excepción incompatibles, nunca mezclar ambos.

+0

hay muchas otras sutilezas que lo hacen peligroso en general. Por ejemplo, si la DLL se compila con una versión diferente de la CRT, se le atornillará (por ejemplo, depuración frente a versión, o multiproceso frente a subproceso único).Además, el CRT almacena cierto estado en el nivel de módulo, no en el nivel de proceso (por ejemplo, hModule o información de seguimiento de memoria), por lo que cuando transmite objetos dependientes de CRT a través de límites de DLL, todos estos elementos pueden perder sincronía. Y los errores están en tiempo de ejecución, y pueden ser muy sutiles/head-scratchers. En general, evita esto. – tenfour

0

El ejemplo que proporcionó debería funcionar bien; sin embargo, con las DLL, si lanza una excepción alojada en el montón, se bloqueará si el consumidor de la DLL intenta liberar la excepción asignada en el montón.

3

Con respecto a GCC, hay al menos un caso en el que las excepciones de captura de GCC generados bibliotecas compartidas pueden ser problemáticos, es decir, cuando el olvido para exportar el throw tipo de poder de la biblioteca compartida cuando la visibilidad símbolo es "hidden" por defecto. La página GCC Visibility Wiki entra en detalles sobre el problema y sobre cómo prevenirlo.

No estoy seguro de si las DLL de Windows tienen problemas similares, pero parece probable.

1

Gotcha general cuando se trata de archivos DLL y excepciones:

no implementan la línea clase de excepciones en la cabecera. Finalizará con tablas duplicadas e información RTTI, lo que provocará que las excepciones no queden atrapadas en el código de uso (debido a la duplicación, la excepción se considera de otro tipo).

Los detalles:

http://marcmutz.wordpress.com/2010/08/04/fun-with-exceptions/

Cuestiones relacionadas