visualc&x2B+;非托管代码:对C+使用/EHa或/EHsc+;例外情况? 如果我在非托管C++、VisualStudio 2008或更大版本中创建一个新项目,我想使用哪种异常处理模型?

visualc&x2B+;非托管代码:对C+使用/EHa或/EHsc+;例外情况? 如果我在非托管C++、VisualStudio 2008或更大版本中创建一个新项目,我想使用哪种异常处理模型?,c++,visual-studio-2008,exception,access-violation,seh,C++,Visual Studio 2008,Exception,Access Violation,Seh,我知道/EHa选项会导致代码效率降低,并且还会捕获SEH异常,对吗 p>所以我一直避开这个选项,通常是用/eHSC,所以我只捕获C++中的异常,这些异常实际上是在catch(…)处理程序中被抛出,而不是捕获访问违规和其他结构化的执行。如果我的代码中存在访问冲突,我不希望它被catch(…){}掩盖 我和其他希望catch(…){}什么也不做的人一起编写代码,他们甚至希望它在出现访问冲突时这样做,这对我来说是一个非常糟糕的主意。如果有一个错误是由于糟糕的编码,你不想把你的手指插入你的耳朵,大声说

我知道/EHa选项会导致代码效率降低,并且还会捕获SEH异常,对吗

<> p>所以我一直避开这个选项,通常是用/eHSC,所以我只捕获C++中的异常,这些异常实际上是在catch(…)处理程序中被抛出,而不是捕获访问违规和其他结构化的执行。如果我的代码中存在访问冲突,我不希望它被catch(…){}掩盖

我和其他希望catch(…){}什么也不做的人一起编写代码,他们甚至希望它在出现访问冲突时这样做,这对我来说是一个非常糟糕的主意。如果有一个错误是由于糟糕的编码,你不想把你的手指插入你的耳朵,大声说“啦啦啦!”这样你就不必让程序崩溃了?事实上,如果代码现在由于编码错误而处于错误状态,您真的希望代码继续吗

所以我的一般想法是/EHa创建了更大/更慢的代码,它允许程序员编写代码,如果出现致命错误,它将继续在未定义的状态下运行

顺便说一句,我说的是应用程序和服务代码,这是我们正在编写的大部分内容。不是低级设备驱动程序或类似的东西


请考虑一下您的想法。

我使用/EHa是因为使用.NET interop是安全的,而/EHsc可能不是;例如,见

但是,如果对于特定的代码来说,额外的性能真的很重要,并且您不需要.NET(或任何其他)兼容性,那么当然,/EHsc听起来不错


/EHsc和/EHa都不能捕获大多数内存错误,因此使用它们来捕获访问冲突是没有希望的。首先,它抑制了一个优化,它省略了异常过滤器,如果代码分析器无法看到任何可能抛出C++异常的代码,则会自动调用本地类变量的析构函数。这使得堆栈展开对于任何异常都安全,而不只是C++异常。这些异常过滤器的开销是x86上的时间和x86和x64上的空间

是的,它改变了catch(…)的行为,它现在也过滤了任何SEH异常,而不仅仅是C++。这确实是一场赌博,因为你抓住了所有真正讨厌的东西,异步硬件异常。虽然我个人认为,不排除所有的C++异常也是非常可防御的,但是,对于程序状态发生了什么程度的变异以及为什么失败,您仍然有一个模糊的概念。


实际上,您需要切换到使用
\uuuuuu try/\uuuu except
,这样您就可以编写自己的异常过滤器,避免捕获坏的异常。C++异常的异常代码是0xE04D5334(“MSC”)。使用_set_se_translator()将是另一种方法。

在任何情况下都不应该试图捕获访问冲突。这是我的理解。。。但是我有人在写catch(…){},如果选择了/EHa,那么我相信这会掩盖访问冲突。捕获(…){cleanup_stuff;throw;}是一回事,但即使在这种情况下,如果捕获的是访问违规,您确定cleanup_stuff会完成它的工作吗?您的状态不好,因此我可能认为程序最好只是在那里崩溃。我在一个客户机/服务器系统上工作,如果服务器出现异常(理想情况下是任何异常,包括访问冲突),我希望在允许服务器线程崩溃之前向客户机发送异常消息。否则,服务器将停止响应。EHa绝对是您对可靠性至关重要的服务等的要求。谈论访问违规问题听起来不太可能,但别忘了被零除可能会破坏您的服务@NickWestgate完全同意,在高可用性服务中,有时通过适当的接口隔离代码中不太可靠的部分并不难,并捕获接口后面出现的所有错误(包括除数为零),并且仍然对程序的状态有很好的了解。回答很好,您能否进一步详细说明这些异常过滤器的开销是x86上的时间和x86和x64上的空间。部分?更具体地说,为什么x64上没有时间开销?x64使用查找表将异常地址映射到catch处理程序,该表是在编译时生成的。x86将处理程序地址推送到try块条目的堆栈上。