在Visual Studio 2010中混合异常处理模型会产生什么后果?

时间:2011-06-29 16:45:38

标签: c++ windows visual-studio seh

我建立了第三方静态库,Enable C++ Exceptions设置为(未指定/EH标志)。从启用C ++异常(/EHa)构建的代码调用它会产生什么后果?如果从库中抛出结构化异常,是否可以可靠地调用主应用程序提供给_set_se_translator的函数? (我的实验表明它会,但只是想知道这是否是定义的行为)。

混合/EH异常处理模型时还有其他考虑因素吗?

2 个答案:

答案 0 :(得分:5)

调用代码中没有启用异常的代码不会产生任何问题 - 这与调用外部C函数或其他类似的函数没什么区别。

从代码调用没有启用异常的代码(进入异常启用代码)可能不会在异常禁用代码中包含正确的堆栈展开语义,这意味着你将打破那些不变量代码,除非它专门用于处理异常。 (例如,一些库(例如ANTLR)分配块中的所有内存并使用户代码一次性释放所有内容,允许使用异常而不会泄漏,即使它们本身不使用异常)。

Raymond Chen有一篇关于C ++异常处理如何在MSVC ++上工作的内容的文章。长话短说,它建立在Windows的SEH之上。因此,它应该与您在例如SEH中引发SEH异常时的行为类似。 C代码。 (但是,我自己没有验证过这个)

答案 1 :(得分:5)

根据MSDN,我们可以混合使用/EHa and /EHsc

  

两个异常处理模型(同步和异步)完全兼容,可以在同一个应用程序中混合使用。

但是这个规则似乎有一个例外,那就是将异常从非托管(/ EHsc)传递给managed (/clr)。托管代码使用结构化异常处理(SEH)捕获所有异常,这会在展开堆栈时导致unmanaged destructors not to be called。有不同的解决方法:

  1. 将非托管代码更改为使用/ EHa而不是/ EHsc。这有一个缺点,即非托管代码中的catch(...)突然会捕获访问冲突和其他疯狂的东西。
  2. 在非托管代码中创建try-catch块,并确保在非托管环境和托管环境之间不会传递异常。

    2.1。可能的中间道路是确保在将异常从非托管世界传递到托管世界时,不会要求调用析构函数。在非托管代码中创建一个try-catch包装器,然后在catch-block中将异常重新抛出到托管世界。