/EH(异常处理模型)
更新: 2008 年 7 月
指定编译器要使用的异常处理模型,并且销毁由于异常的原因将超出范围的 C++ 对象。如果未指定 /EH,编译器将捕获结构化异常和 C++ 异常,但将不销毁由于异常的原因而将超出范围的 C++ 对象。
/EH{s|a}[c][-]
参数
a
捕获异步(结构化)异常和同步 (C++) 异常的异常处理模型。s
仅捕获 C++ 异常并通知编译器假定 extern C 函数确实引发了异常的异常处理模型。c
如果与 s (/EHsc) 一起使用,则仅捕获 C++ 异常并通知编译器假定 extern C 函数从未引发 C++ 异常。/EHca 等效于 /EHa。
备注
使用 /EHs 指定同步异常处理模型(没有结构化异常处理异常的 C++ 异常处理)。如果使用 /EHs,则 catch 子句将不会捕获异步异常。此外,在 Visual C++ 2005 中,当生成异步异常时,即使处理了异步异常也不会销毁范围内的所有对象。在 /EHs 下,catch(...) 仅捕获 C++ 异常。将不捕获访问冲突和 System.Exception 异常。
使用 /EHa 可指定异步异常处理模型(具有结构化异常处理异常的 C++ 异常处理)。/EHa 可能导致映像性能较差,因为编译器不会积极地优化 try 块,即使编译器没有发现 throw 也如此。
如果希望捕获由 throw 以外的内容引发的异常,请使用 /EHa。下面的示例将生成异常:
// compiler_options_EHA.cpp
// compile with: /EHa
#include <iostream>
#include <excpt.h>
using namespace std;
void fail() { // generates SE and attempts to catch it using catch(...)
try {
int i = 0, j = 1;
j /= i; // This will throw a SE (divide by zero).
printf("%d", j);
}
catch(...) { // catch block will only be executed under /EHa
cout<<"Caught an exception in catch(...)."<<endl;
}
}
int main() {
__try {
fail();
}
// __except will only catch an exception here
__except(EXCEPTION_EXECUTE_HANDLER) {
// if the exception was not caught by the catch(...) inside fail()
cout << "An exception was caught in __except." << endl;
}
}
/EHc 选项需要指定 /EHs 或 /EHa。使用 /clr(公共语言运行库编译)暗指 /EHa(/clr /EHa 是冗余的)。如果在 /clr 后使用 /EHs[c],则编译器将生成一个错误。优化不会影响此行为。当捕获异常时,编译器将为与该异常在同一范围内的对象调用类析构函数。如果未捕获异常,则不会运行这些析构函数。
有关 /clr 下的异常处理限制的信息,请参见 _set_se_translator。
可以使用符号 - 清除该选项。例如,/EHsc- 解释为 /EHs /EHc- 并且等价于 /EHs。
有关更多信息,请参见Exception Handling: Default Synchronous Exception Model。
在 Visual Studio 开发环境中设置此编译器选项
打开此项目的“属性页”对话框。有关详细信息,请参见如何:打开项目属性页。
单击“C/C++”文件夹。
单击“代码生成”属性页。
修改“启用 C++ 异常”属性。
或者,也可以使用以下过程:
在 Visual Studio 开发环境中设置此编译器选项
单击“C/C++”文件夹。
单击“代码生成”属性页。
将“启用 C++ 异常”设置为“否”。
单击“命令行”属性页。
在“附加选项”框中键入编译器选项。
以编程方式设置此编译器选项
- 请参见 ExceptionHandling。
请参见
参考
修订记录
日期 |
修订记录 |
原因 |
---|---|---|
2008 年 7 月 |
修订了有关 /EHa 选项如何会生成性能较低的映像的说明。在示例的 try 块中增加了最后一条语句以防止出现不需要的优化。 |
信息补充。 |