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

Sco*_*ott 7 c++ windows seh visual-studio

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

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

Bil*_*eal 5

调用不启用不应产生任何问题异常的代码-这只不过是调用外部C函数或性质不同的东西.

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

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


Rol*_*sen 5

根据MSDN,然后允许混合/ EHa和/ EHsc:

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

但是这个规则似乎有一个例外,那就是将异常从非托管(/ EHsc)传递到托管(/ clr).托管代码使用结构化异常处理(SEH)捕获所有异常,这会导致在展开堆栈时不调用非托管析构函数.有不同的解决方法:

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

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