美文网首页
异常处理和非本地跳转

异常处理和非本地跳转

作者: 漫游之光 | 来源:发表于2019-02-16 21:14 被阅读0次

异常处理

异常处理机制允许程序中独立开发的部分能够在运行时才出现的问题进行通信并做出相应的处理。异常使得我们能够将问题的检测与解决过程分离开来。程序的一部分负责检测问题的出现,然后解决该问题的任务传递给程序的另一部分。

C++中,可以使用throw关键词抛出一个异常。当执行一个throw时,跟在throw后面的语句将不再被执行。相反,程序的控制权从throw转移到与之匹配的catch模块。即程序暂停当前函数的执行过程并立即开始寻找与异常匹配的catch子句。当throw出现在一个try语句块内时,检查与该try块关联的catch子句。如果找到了匹配的catch,就使用该catch处理异常。如果这一步没找到匹配的catch且该try语句嵌套在其他try块中,则继续检查与外层try匹配的catch子句。如果还是找不到匹配的catch,则退出当前函数,在调用当前函数的外层函数中继续寻找。这个过程称为栈展开。

在栈展开的过程中,位于调用链上的语句块可能会提前退出,局部对象会进行销毁,如果局部对象是类类型,会自动调用其析构函数。下面是一个例子:

#include <iostream>
using namespace std;

class Base{
  public:
    Base(){
        cout << "Base()" << endl;
    }
    ~Base(){
        cout << "~Base()" << endl;
    }
};

int divide(int a, int b) noexcept(false){
    Base base;
    if (b == 0){
        cout << "b = 0"<<endl; /* automatically call objects destructor int the stack */
        throw b;
    }
    cout << "b != 0" << endl;
    return a / b;
}

int main(int argc, char const *argv[]){
    try{
        divide(10,0);
    }catch(int e){ /* int exceptions */
        cout<<"divide by zero"<<endl;
    }catch( ... ){ /* other exceptions */
        throw; /* didn't handle this exception */
    }
    return 0;
}

值得注意的是,C++的异常处理和Java是不同的。C++的异常处理只能处理throw中抛出的异常,而不能处理语句的异常,如try语句中有一个除0操作,仍然会导致程序退出,而在Java中不会。

非本地跳转

C语言提供一种用户级别的异常控制流形式,称为非本地跳转,它将控制字节从一个函数转移到另一个当前正在执行的函数,而不需要经过正常的调用-返回序列。非本地跳转时通过setjmp和longjmp函数来提供的。

#include<setjmp.h>
int setjmp(jmp_buf env); /* 直接调用setjmp返回0,从longjmp返回非0 */
int longjmp(jmp_buf env, int retval);

setjmp函数在env缓冲区中保存当前的调用环境,以供后面的longjmp使用,并返回0。调用环境包括程序计数器、栈指针和通用目的寄存器。longjmp函数从env缓冲区恢复调用环境,然后触发一个从最近一次初始化env的setjmp调用中返回。然后setjmp返回,并带有非零的返回值retval。下面是具体的例子:

#include<stdio.h>
#include<stdlib.h>
#include<setjmp.h>

int divide(int a, int b, jmp_buf jmpBuf){
    char *s = (char *)malloc(sizeof(char) * 10);
    if(b == 0){
        free(s); 
        printf("b == 0\n");
        longjmp(jmpBuf,1);
    }
    printf("b != 0\n");
    return a/b;
}

int main(int argc, char const *argv[])
{
    jmp_buf jmpBuf;
    if( (setjmp(jmpBuf)) !=0 ){
        printf("divide by zero\n");
        goto end;
    }
    divide(10,0,jmpBuf);
end:   
    return 0;
}

相关文章

  • 异常处理和非本地跳转

    异常处理 异常处理机制允许程序中独立开发的部分能够在运行时才出现的问题进行通信并做出相应的处理。异常使得我们能够将...

  • 5嵌套异常处理

    异常处理程序可以嵌套,以便内部域中引发的异常可以由本地异常处理程序和任意数量的包含异常处理程序处理。这种设计允许由...

  • 2.1.3 Python面向对象之异常处理

    点击跳转笔记总目录 Python面向对象之异常处理 一、错误与异常 二、异常处理 三、什么时候用异常处理 一、错误...

  • 异常处理

    JAVA严格的异常处理机制和类型检查机制 异常处理手贱异常非手贱异常 异常链处理 异常是在程序出错的时候能知道程序...

  • springMVC(3)异常处理与拦截器与SSM整合

    7. 异常处理步骤:7.1 编写自定义异常类(提示信息) 7.2 编写异常处理器 7.3 配置异常处理器(跳转到错...

  • Java核心技术卷1异常处理阅读笔记

    异常处理 关于Java核心技术 卷1 的 异常处理章节记录 1. 检查型异常和非检查型异常 异常可以分为: che...

  • Java异常处理-检查性异常、非检查性异常、Error

    一、Java异常处理详解 Java异常处理-笔记中的@doublefan讲解得非常通熟易懂 二、检查型异常和非检查...

  • Spring异常处理

    1、配置简单异常处理器(此方法用于简单处理异常,即只能做跳转) 其中Key对应需要处理的异常种类,value对应需...

  • 非本地跳转函数setjmp和longjmp

    C语言提供了一种用户级的异常控制流形式,称为非本地跳转(nonlocal jump),它可以将控制流直接从一个函数...

  • SpringMVC配置跳转html、jsp

    依赖 配置文件 配置统一跳转错误页面404.html 异常处理器 注册异常处理器

网友评论

      本文标题:异常处理和非本地跳转

      本文链接:https://www.haomeiwen.com/subject/mzuieqtx.html