在VisualStudio2010中混合异常处理模型的后果是什么? 我有第三个静态库,用 >启用C++异常> /Cuff>设置为 NO>强>( /EH < /COD>标志未指定)。从启用C++异常的代码调用(“代码> /EHA < /COD>”),调用它会产生什么后果?如果从库中抛出结构化异常,主应用程序提供给_set_se_translator的函数是否可靠调用?(我的实验表明它会,但只是想知道这是否是定义的行为)

在VisualStudio2010中混合异常处理模型的后果是什么? 我有第三个静态库,用 >启用C++异常> /Cuff>设置为 NO>强>( /EH < /COD>标志未指定)。从启用C++异常的代码调用(“代码> /EHA < /COD>”),调用它会产生什么后果?如果从库中抛出结构化异常,主应用程序提供给_set_se_translator的函数是否可靠调用?(我的实验表明它会,但只是想知道这是否是定义的行为),c++,windows,visual-studio,seh,C++,Windows,Visual Studio,Seh,混合使用异常处理模型时,还有其他考虑吗?将调用到未启用异常的代码中不会产生任何问题——这与调用外部C函数或类似性质的东西没有什么不同 从未启用异常的代码调用(到启用异常的代码中)可能不会在禁用异常的代码中包含正确的堆栈展开语义,这意味着您将破坏该代码的不变量,除非它专门设计用于处理异常。(例如,一些库(例如ANTLR)在一个块中分配所有内存,并让用户代码一次释放所有内容,允许使用异常而不泄漏,即使它们本身不使用异常) 有一篇关于C++如何在MSVC++上处理异常的文章。长话短说,它建立在Wind

混合使用异常处理模型时,还有其他考虑吗?

调用到未启用异常的代码中不会产生任何问题——这与调用外部C函数或类似性质的东西没有什么不同

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

有一篇关于C++如何在MSVC++上处理异常的文章。长话短说,它建立在Windows的SEH之上。因此,它的行为应该类似于在例如C代码中抛出SEH异常时发生的情况。(然而,我自己还没有验证过这一点)

根据以下规则,允许一个人混合:

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

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

  • 将非托管代码更改为使用/EHa而不是/EHsc。这样做的缺点是,非托管代码中的catch(…)会突然捕获访问冲突和其他疯狂的东西
  • 在非托管代码中创建try-catch块,并确保在非托管世界和托管世界之间不传递任何异常

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


  • 从技术上讲,标准会说这会导致违反ODR的未定义行为。然而,我假设你想要一个更具体的解释(这就是为什么这是一个评论)。@Billy ONeal:你一禁用异常就点击UB;混血不会让事情变得更糟。UB没有学位。@MSalters:Lol——我都没想到。没错。是的,我意识到我在非标准领域。我只是想知道Microsoft实现是否定义了这种情况下的行为。所有Windows问题都会返回到Raymond Chen.:)谢谢关于托管与非托管交互的详细解释,这是一个很好的答案。您还可以详细说明为什么在链接过期的情况下不调用析构函数吗?我猜想当异常捕捉方期望Seh风格异常时,抛出侧使用C++异常,堆栈解体的THONE会变得“看不见”到catch方。