如果同时指定 EHsc 和 EHa 会发生啥

Posted

技术标签:

【中文标题】如果同时指定 EHsc 和 EHa 会发生啥【英文标题】:What happens if both EHsc and EHa are specified如果同时指定 EHsc 和 EHa 会发生什么 【发布时间】:2011-10-12 11:14:18 【问题描述】:

我正在处理遗留代码。

要修复一些错误,我必须给一些文件提供 EHa。我测试了在构建时为整个项目同时提供 EHsc 和 EHa。这解决了我的问题,但警告说编译器正在用 EHa 覆盖 EH。 (选项顺序为:/EHsc /EHa) 只有在构建需要 EHa 的文件时才会出现此警告。它不会出现在只需要 EH 的源文件中。

<name of the file that needs EHa>\cl : warning D9025 : overriding '/EHs' with '/EHa'

我的问题是,这个警告是否说明了实际发生的情况? EHa 是否仅应用于实际需要 EHa 的源文件? (其他不需要EHa的文件是用EHsc构建的吗?)

谢谢。

【问题讨论】:

【参考方案1】:

/EHa 是“更强”的设置。它暗示 /EHsc 但确保即使在抛出和捕获非 C++ 异常时也会调用 C++ 析构函数。 Windows 中的 SEH 异常。简单的 /EHsc 允许代码生成器优化代码并在它看不到括号中的代码抛出 C++ 异常的方法时省略异常过滤器。这种优化不适用于 SEH 异常,例如任何语句都可能引发 AccessViolation。

只有在程序中使用非标准的 __try 和 __except 关键字来捕获 SEH 异常时,才需要 /EHa。 AccessViolation、DivisionByZero、浮点异常、与使用 SEH 处理自己的异常的语言运行时互操作,等等。如果您使用它们,那么您必须确保 all 您的代码是使用 /EHa 编译的。当捕获到 SEH 异常时,错误可能会导致内存泄漏。

【讨论】:

代码使用set_se_translator()。并且此功能仅用于少数文件。我想用 EHa 编译使用该功能的文件,并以性能更友好的 EHsc 休息。目前的方法可以做到这一点吗?谢谢 MSDN 文档非常清晰:You must use /EHa when using _set_se_translator。几个文件不算。异常过滤器开销在 32 位代码中非常小,在 64 位代码中没有。您是在进行微观优化还是实际测量 如果开销很小,我认为我不需要担心。再次感谢。但我想澄清几件事。据我了解,MSDN 指的是使用 _set_se_translator() 的 C++ 文件。其他不使用此功能的文件呢?我觉得在他们身上应用 EHa 是没用的。你能指导我找到一个好的网址或一本书吗(我想是时候深入研究一下编译器了) “当您在程序中使用非标准的 __try 和 __except 关键字来捕获 SEH 异常时,您只需要 /EHa” - 这对我来说似乎错误。我一直认为您需要 /EHa 来捕获带有 catch(...) 的 SEH 异常——__except itself 根本不应该受到它的影响。当然,在 SEH 的情况下不会运行潜在的 d'tors,但仍应调用 __except 过滤器。【参考方案2】:

是的,警告会告诉您会发生什么,因为发生的事情可能不是您想要的。这就是编译器警告背后的全部想法。

编译器不知道也不关心哪些文件“实际上需要 EHa”(在文件被编译之前,编译器无法告诉任何关于该文件的信息)。它应用您告诉它应用的选项。您告诉它同时应用这两者,它会告诉您它将此解释为您希望应用 EHA。

在调用编译器时指定每个矛盾的标志意味着“尝试所有可能的编译器选项组合,直到找到一个可行的组合”。

【讨论】:

我没有尝试所有可能的组合。我主要担心的是使用 EHa 可能会导致性能下降。如果 EHa 应用于每个源文件,那么我计划研究一种将 EHa 应用于实际需要它的文件并使用 EHsc 编译其他文件的方法。唯一的问题是我不熟悉这里使用的基于 Visual C++ 的构建系统。谢谢 您可以打开单个文件的属性并为这些特定文件设置不同的标志。但我希望您在担心可能性能下降之前对其进行基准测试。过早的优化等等

以上是关于如果同时指定 EHsc 和 EHa 会发生啥的主要内容,如果未能解决你的问题,请参考以下文章

MSVC - /EHsc 与 /EHa(同步与异步异常处理)

如何关闭Microsoft编译器(cl)中的异常?

如果在 java 中没有指定修饰符会发生啥? [复制]

如果未指定 Internet Explorer 兼容性视图会发生啥

当 Grails BuildConfig 范围没有指定组织时会发生啥?

当 printf 没有指定格式说明符时会发生啥?