2011-06-29 13 views
6

Tengo una biblioteca estática de terceros construida con Enable C++ Exceptions establecida en No (/EH marca no especificada). ¿Cuáles son las consecuencias de llamar desde código creado con excepciones de C++ habilitadas (/EHa)? Si se lanza una Excepción estructurada desde el interior de la biblioteca, ¿se llamará de manera confiable a la función proporcionada a _set_se_translator por la aplicación principal? (Mis experimentos muestran que sí, pero me pregunto si este es un comportamiento definido).¿Cuáles son las consecuencias de mezclar modelos de manejo de excepciones en Visual Studio 2010?

¿Hay alguna otra consideración al mezclar modelos de entrega de excepciones /EH?

+0

Técnicamente, el estándar diría que causa un comportamiento indefinido para romper ODR. Sin embargo, supongo que quieres una explicación más concreta (y por eso es un comentario). –

+3

@Billy ONeal: golpeas UB tan pronto como desactivas las excepciones; la mezcla no puede empeorar las cosas. UB no viene en grados. – MSalters

+0

@MSalters: Lol - ni siquiera pensé en eso. Es verdad. –

Respuesta

5

Llamando al código que no tiene excepciones habilitadas no debería producir ningún problema, esto no es diferente a llamar a una función C externa o algo por el estilo.

Calling de código que no tiene excepciones habilitados (en código habilitado excepción) probablemente no contener la pila correcta desenrollar la semántica en el código bloqueado excepción, lo que significa que será romper invariantes de ese código, a menos que fue diseñado específicamente para trabajar con excepciones. (Por ejemplo, algunas bibliotecas (por ejemplo, ANTLR) asignan toda la memoria en un bloque y hacen que el código de usuario libere todo a la vez, permitiendo que las excepciones se utilicen sin fugas aunque no usen excepciones).

Raymond Chen tiene un buen artículo sobre las entrañas de cómo el manejo de excepciones de C++ funciona en MSVC++. Para resumir, está construido sobre el SEH de Windows. Por lo tanto, debe comportarse de manera similar a lo que sucede si lanza una excepción SEH en, por ejemplo, Código C (Sin embargo, no he verificado esto por mí mismo)

+1

Todas las preguntas de Windows nos llevan a Raymond Chen. :) ¡Gracias! – Scott

4

De acuerdo con la MSDN entonces uno se permite mezclar /EHa and /EHsc:

Los dos modelos de manejo de excepciones, síncrona y asíncrona, son totalmente compatibles y se pueden mezclar en la misma aplicación.

Pero parece haber una excepción a esta regla, y es cuando se pasan excepciones de no gestionadas (/ EHsc) a managed (/clr). Los códigos administrados detectan todas las excepciones utilizando el manejo estructurado de excepciones (SEH), y esto causa unmanaged destructors not to be called al desenrollar la pila. Hay diferentes soluciones:

  1. Cambie el código no administrado para usar/EHa en lugar de/EHsc. Esto tiene la desventaja de que la captura (...) dentro del código no administrado repentinamente atrapará violaciones de acceso y otras cosas locas.
  2. Crea un bloque try-catch dentro del código no administrado y asegúrate de que no se pasen excepciones entre el mundo no administrado y el mundo administrado.

    2.1. El posible camino intermedio es garantizar que no se espere que se invoquen destructores al pasar la excepción del mundo no administrado al mundo administrado. Dentro del código no administrado, haga un contenedor try-catch, y luego en el catch-block vuelva a lanzar la excepción en el mundo administrado.

Cuestiones relacionadas