结构化异常
- 结构化异常是一种编程方法,将软件主要功能编写与软件异常情况处理相分离。
- 结构化异常可以使得程序更健壮,同时利用结构化异常的某些特点也可以使得代码结构更简洁(如使用终止处理程序来解决多if return情况)。
- 编译器为结构化异常做底层实现,如在进入或离开异常处理代码块时,编译器必须生成一些特殊的代码,以及生成一些关于支持SEH的数据结构表,还必须提供回调函数给操作系统调用,以便系统遍历异常代码块。
- 编译器还负责准备进程的栈框架和其他一些内部信息,这些信息都是操作系统需要使用或者引用的。
- 因为是编译器来实现的SEH,所以不同编译器实现的方式是不同的。
终止处理程序
- 被保护代码以retrun,goto,longjump,continue,break等形式提前退出的,终止处理程序都将会被调用。
- 编译器保证finally块代码在try块中return之前被执行。如果return具有返回值,会先将返回值存到一个临时变量里面,再执行finally块。如果finally块中也有return,则也同样将return的返回值保存到这个临时变量里面(!此行为相当于覆盖了try块的返回值),此时finally块执行完毕,调整回原try块中的return处,执行return操作。将临时变量return。
- 上述所描述过程可称为局部展开。
- 应该避免在try块中非正常退出,这样做会引起性能损失。
- ExitProcess,Terminate函数在try块中时,不会再执行finally块。
- 使用终止处理程序可以简化多if return程序结构。
- __leave关键字可以跳出try块,执行到finally块,性能相对而言损失较少。
- 使用终止处理程序简化多if return结构代码示例:
HANDLE hFile = NULL;
PVOID pvBuf = NULL;
__try
{
DWORD dwNumBytesRead;
BOOL bOK;
HANDLE hFile = CreateFile(...);
if(hFile == INVALID_HANDLE_VALUE)
__leave;
pvBuf = VirtualAlloc(...);
if(pvBuf == NULL)
__leave;
bOK = ReadFile(...);
if(!bOK || )
__leave;
}
__finally
{
if(pvBuf != NULL)
VirtualFree(pvBuf,...);
if(hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
}