我正在用SEH做一些实验。在我的代码中,我在__try子句中编写了错误导致块,在__except()中编写了一个处理程序。
__try{
Test *pTest = 0;
int k = pTest->GetValue();
cout << "continue after exception" << endl;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION,EXCEPTION_EXECUTE_HANDLER)
{
cout << "caught!!" << endl;
}
cout << "Exception handled" << endl;
__except()的第二个参数是 -
EXCEPTION_CONTINUE_SEARCH无法识别异常。继续在堆栈中搜索一个处理程序,首先是包含try-except语句,然后是下一个最高优先级的处理程序。
EXCEPTION_CONTINUE_EXECUTION异常被识别但被驳回。在异常发生的地方继续执行。
EXCEPTION_EXECUTE_HANDLER识别异常。通过执行__except复合语句将控制转移到异常处理程序,然后在异常发生时继续执行。
当我使用EXCEPTION_CONTINUE_EXECUTION / EXCEPTION_EXECUTE_HANDLER时,它不会在异常发生时继续执行(可能是我误解了异常发生点的含义)。 当我在调试模式下运行它时,输出是
caught
Exception handled
当我在发布模式下运行时,输出为
continue after exception
Exception handled
我无法理解为什么表现不同。有人请帮忙。
答案 0 :(得分:4)
@Joachim正确指出了逗号运算符问题。
我认为,__except()
应如下所示:
__except((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) ?
EXCEPTION_EXECUTE_HANDLER :
EXCEPTION_CONTINUE_SEARCH)
如果异常是访问冲突,这将使异常处理程序执行。如果不是,则异常将传播到最近的外部__try
,如果有的话。
我担心pTest
是指向类的指针,为了执行GetValue()
,可能不需要取消引用它,并且编译器会识别出在发布模式下启用优化时。或者甚至可能将GetValue()
视为无用,并且不会生成任何代码来调用它。编译器也可能看到解除引用NULL指针会导致未定义的行为,并决定在编译时通过拧紧代码来惩罚它,它完全有权这样做。例如,gcc因这样做而臭名昭着。
答案 1 :(得分:1)
表达式
GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION,EXCEPTION_EXECUTE_HANDLER
不符合您的预期。它的作用是将GetExceptionCode()
的结果与EXCEPTION_ACCESS_VIOLATION
进行比较,但整个表达式的结果为EXCEPTION_EXECUTE_HANDLER
。
详细了解逗号运算符at Wikipedia。
你想做的事情可能是:
GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION || GetExceptionCode() == EXCEPTION_EXECUTE_HANDLER