如果我要使用非托管 C++、Visual Studio 2008 或更高版本创建新项目,我想要使用哪种异常处理模型?

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

因此,我一直避开该选项,通常使用 /EHsc,这样我在 catch(...) 处理程序中只捕获实际抛出的 C++ 异常,而不捕获访问冲突和其他结构化执行。如果我的代码中存在访问冲突,我不希望它被 catch(...) {} 掩盖。

我和其他人一起编写代码,他们希望 catch(...) {} 不执行任何操作,甚至希望它在发生访问冲突时执行此操作,这对我来说似乎是一个非常糟糕的主意。如果由于编码不好而导致错误,您不想将手指伸入耳朵中,并大声说“ La la la la La!”这样您就不必让程序崩溃了吗?事实上,如果代码现在由于编码错误而处于错误状态,您真的希望代码继续吗?

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

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

请权衡一下你的想法。

有帮助吗?

解决方案

/eha做了两件事。首先,它抑制了一种优化,该优化省略了异常过滤器,该过滤器如果代码分析仪看不到任何可能抛出C ++异常的代码,则自动调用本地类变量的破坏者。这使得堆栈在任何例外都可以安全,而不仅仅是C ++例外。这些例外过滤器的开销是x86的时间,x86和x64上的空间。

是的,它改变了捕获的行为(...),现在还过滤了任何SEH例外,而不仅仅是C ++。这确实是一场赌博,因为您会发现所有真正令人讨厌的东西,异步硬件异常。尽管我个人认为,捕获所有C ++例外的情况也不是很容易辩护,但您仍然有一个模糊的想法,该程序状态在多大程度上变得突变以及为什么失败。

实际上,您需要切换到使用 __try/__except 这样您就可以编写自己的异常过滤器,并避免捕获不良的过滤器。 C ++异常的异常代码是0XE04D5343(“ MSC”)。使用_set_se_translator()将是另一种方法。

其他提示

我使用 /EHa 是因为它对于 .NET interop 是安全的,而 /EHsc 可能不安全;看 当本机 (C++) 异常传播到 CLR 组件时,不会调用析构函数 例如。

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

/EHsc 和 /EHa 都不能捕获大多数内存错误,因此使用它们来捕获访问冲突是没有希望的情况。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top