2010-12-10 140 views
14

如果我在非托管C++,Visual Studio 2008或更高版本中创建一个新项目,我想要使用哪种异常处理模型?Visual C++非托管代码:对于C++异常,使用/ EHa还是/ EHsc?

我知道/ EHa选项导致代码效率较低,并且还捕获SEH异常,对吗?所以我一直在清除那个选项,通常使用/ EHsc,这样我只捕获实际抛出的C++异常,而不捕获访问冲突和其他结构化的错误,catch(...)处理程序。如果我的代码中存在访问冲突,我不希望它被catch(...){}掩盖。

我与其他人希望catch(...){}什么也不做,他们甚至希望它做到这一点,如果有访问冲突,这对我来说似乎是一个非常糟糕的主意。如果由于编码错误而导致错误发生,您不希望将手指放在耳朵中,并大声说出“La la la la la!”。所以你不必让程序崩溃?事实上,如果由于编码错误导致代码现在处于不良状态,您是否真的希望代码继续?

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

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

请考虑你的想法。

回答

16

/EHa做了两件事。首先,它抑制了一种优化,它忽略了如果代码分析器无法看到任何可能抛出C++异常的代码时自动调用本地类变量的析构函数的异常过滤器。这使得堆栈展开对于任何类型的异常都是安全的,而不仅仅是C++异常。这些异常过滤器的开销是x86和X64上的时间和x86和x64上的空间。

是的,它改变了catch(...)的行为,它现在也过滤任何SEH异常,而不仅仅是C++。这确实是一场赌博,因为你抓住了所有非常讨厌的东西,即异步硬件异常。尽管我个人认为捕捉所有C++异常也是不可取的,但是对于程序状态发生了什么变化以及失败的原因,您还有一个模糊的想法。

实际上,您需要切换到使用__try/__except,以便您可以编写自己的异常过滤器并避免发现错误。 C++异常的例外代码是0xe04d5343(“MSC”)。使用_set_se_translator()将是另一种方法。

4

我使用/ EHa,因为它与.NET interop安全,而/ EHsc可能不会;例如,参见Destructors not called when native (C++) exception propagates to CLR component。但是,如果对于特定的代码位来说,额外的性能真的很重要,并且你不需要.NET(或其他任何)兼容性,那么当然,/ EHsc听起来很不错。

既不/ EHsc也不/ EHa捕获大多数内存错误,所以使用这些来捕获访问冲突是一个无望的情况。

+2

在任何情况下都不应该尝试捕获访问冲突。 – 2010-12-10 23:03:51

+1

这是我的理解......但我有人写catch(...){}如果/ EHa被选中,那么这将埋葬我认为的访问冲突。 这是一回事(...){cleanup_stuff;扔; }但即使在这种情况下,如果这是一个被捕获的访问冲突,你确定cleanup_stuff是要做的吗?你处于一个糟糕的状态,所以我可能会认为该程序最好只是在那里崩溃。 – MarkS 2010-12-10 23:12:45

+3

我正在处理客户端/服务器系统,如果服务器发生异常(理想情况下包括访问冲突),我想在发送服务器线程崩溃之前向客户端发送异常消息。否则,服务器会停止响应。 – 2012-08-10 21:29:30

相关问题