2011-06-29 40 views
6

我有Enable C++ Exceptions内置的第三方静态库设置为没有/EH标志未指定)。从启用C++异常的代码中调用它(/EHa)有什么后果?如果从库中抛出结构化异常,主应用程序提供给_set_se_translator的函数是否会被可靠地调用? (我的实验表明它会,但只是想知道这是否是定义的行为)。在Visual Studio 2010中混合异常处理模型的后果是什么?

混合/EH异常处理模型时是否还有其他注意事项?

+0

从技术上讲,标准会说会导致破坏ODR的未定义行为。我假设你想要更具体的解释,但是(这就是为什么这是一个评论)。 –

+3

@Billy ONeal:当你禁用异常时,你立即击中了UB;混合不会使情况变得更糟。 UB没有进入度数。 – MSalters

+0

@ MSalters:哈哈 - 甚至没有想到这一点。确实如此。 –

回答

5

调用为没有启用异常的代码不应该产生任何问题 - 这与调用外部C函数或此类性质没有什么不同。

调用代码没有启用(为例外启用的码)的异常可能不会包含正确的堆栈在异常残疾人代码展开语义,这意味着你将打破这一代码不变,除非它专门设计用于处理例外情况。 (例如,某些库(例如ANTLR)分配块中的所有内存并让用户代码一次释放所有内容,即使它们本身不使用异常,也可以使用异常而不会泄漏)。

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

+1

所有的Windows问题都回到了Raymond Chen。 :) 谢谢! – Scott

4

按照MSDN再一个就是允许混合/EHa and /EHsc

两个异常处理模式,同步和异步,完全兼容,可混在同一个应用程序中。

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

  1. 更改非托管代码以使用/ EHa而不是/ EHsc。这有一个缺点,那就是在非托管代码中捕获(...)突然会发现访问违规和其他疯狂的东西。
  2. 在非托管代码中创建try-catch块,并确保在非托管世界和托管世界之间不传递任何异常。

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

相关问题