What are the consequences of mixing exception handling models in Visual Studio 2010? What are the consequences of mixing exception handling models in Visual Studio 2010? windows windows

What are the consequences of mixing exception handling models in Visual Studio 2010?


Calling into code which does not have exceptions enabled shouldn't produce any problems -- this is no different than calling an external C function or something of that nature.

Calling from code which does not have exceptions enabled (into exception enabled code) will probably not contain the correct stack unwinding semantics in the exception disabled code, which means you'll be breaking invariants of that code, unless it was specifically designed to work with exceptions. (For example, some libraries (e.g. ANTLR) allocate all memory in a block and have the user code free everything at once, allowing exceptions to be used without leaking even though they themselves do not use exceptions).

Raymond Chen has quite an article about the innards of how C++'s exception handling works on MSVC++. Long story short, it's built on top of Windows' SEH. Therefore it should behave similarly to what happens if you throw a SEH exception in e.g. C code. (However, I've not verified this myself)


According to the MSDN then one is allowed to mix /EHa and /EHsc:

The two exception handling models, synchronous and asynchronous, are fully compatible and can be mixed in the same application.

But there seems to an exception to this rule, and that is when passing exceptions from unmanaged (/EHsc) to managed (/clr). The managed codes catches all exceptions using structured exception handling (SEH), and this causes unmanaged destructors not to be called when unwinding the stack. There are different workarounds:

  1. Change the unmanaged code to use /EHa instead of /EHsc. This has the downside that catch(...) within unmanaged code suddenly will catch access violations and other crazy stuff.
  2. Create try-catch block within the unmanaged code, and ensure that no exceptions are passed between the unmanaged world and the managed world.

    2.1. Possible middle road is to ensure that no destructors are expected to be called when passing exception from unmanaged to managed world. Within the unmanaged code make a try-catch wrapper, and then in the catch-block rethrow the exception into the managed world.