C++异常书写不甚,就很容易造成std::terminate().
[Example:
-
struct TerminalThrow
-
{
-
TerminalThrow(){}
-
TerminalThrow(const TerminalThrow&)
-
{
-
throw 0;
-
}
-
};
-
-
int main(int argc, char* argv[])
-
{
-
try
-
{
-
throw TerminalThrow();
-
int delay = 0;
-
delay = delay;
-
}
-
catch (TerminalThrow ex)
-
{
-
int delay = 0;
-
delay = delay;
-
}
-
-
return 0;
-
}
输出的部分汇编:
-
10242619 8B 65 E8 mov esp,dword ptr [ebp-18h]
-
1024261C E8 5F 56 FC FF call terminate (10207C80h)
-
10242621 C7 45 FC FE FF FF FF mov dword ptr [ebp-4],0FFFFFFFEh
-
10242628 8B 4D F0 mov ecx,dword ptr [ebp-10h]
-
1024262B 64 89 0D 00 00 00 00 mov dword ptr fs:[0],ecx
-
10242632 59 pop ecx
-
10242633 5F pop edi
-
10242634 5E pop esi
-
10242635 5B pop ebx
-
10242636 8B E5 mov esp,ebp
-
10242638 5D pop ebp
-
10242639 C3 ret
结果分析:
汇编中的”call terminate“表明测试程序即将被终止。因为异常在被捕捉到之前又抛出另一个异常,将导致程序终止。异常终止执行顺序:
[ throw TerminalThrow() -> "raise exception" -> "build catch exception" -> TerminalThrow(const TerminalThrow&) -> throw 0 -> std::terminate() ];
解决方法:
1)可行性: 将语句 "catch (TerminalThrow ex) "修改成 "catch (TerminalThrow& ex)",这样就可以避免执行拷贝构造函数"TerminalThrow(const TerminalThrow&) ",就不会执行语句"throw 0;";所以很多情况都建议使用引用参数来捕捉异常。
2)缺点: 在构造函数"TerminalThrow()"中抛出异常,还是会导致程序终止。
--end example]
[15.1.7
Throwing an exception ISO/IEC 14882:2011(E)]
If the exception handling mechanism, after completing evaluation of the expression to be thrown but before the exception is caught, calls a function that exits via an exception, std::terminate is called (15.5.1).
阅读(952) | 评论(0) | 转发(0) |