zoukankan      html  css  js  c++  java
  • C++异常实现与longjmp, setjmp,栈指针EBP, Active Record

    这篇讲的不错:

    http://blog.csdn.net/smstong/article/details/50728022

    首先Active Record

    然后EBP,ESP等指针

    2 通过setjmp和longjmp操纵AR,完成任意跳转

    setjmp/longjmp主要从嵌套的函数调用中跳出来。

    #include <stdio.h>
    #include <setjmp.h>
    
    jmp_buf jb;
    void a();
    void b();
    void c();
    
    int main()
    {
        if(setjmp(jb)==0){
            a();
        }
        printf("after a(); 
    ");
        return 0;
    }
    void a()
    {
        b();
        printf("a() is called
    ");
    }
    void b()
    {
        c();
        printf("b() is called
    ");
    }
    void c()
    {
        printf("c() is called
    ");
        longjmp(jb, 1);
    }

    3 C语言中模拟异常处理

    为了统一处理错误,C++,C#,Java等现代语言引入了异常处理机制。C里面模拟异常的代码大概如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <setjmp.h>
    
    jmp_buf jb;
    
    void f1()
    {
        printf("进入f1()
    ");
        if(0/*正确执行*/){ }
        else {
            longjmp(jb,1);
        }
        printf("退出f1()
    ");
    }
    void f2()
    {
        printf("进入f2()
    ");
        if(1/*正确执行*/) {  }
        else {
            longjmp(jb, 2);
        }
        printf("退出f2()
    ");
    }
    
    int main()
    {
        int r = setjmp(jb);
        if(r==0){
            f1();
            f2();
        }else if(r==1){
            printf("处理错误1
    ");
            exit(1);
        }else if(r==2){
            printf("处理错误2
    ");
            exit(2);
        }
        return 0;
    }

    可以推测,
    • throw要负责两件事情:(1)完成跳转;(2)恢复堆栈AR;
    • try则负责保存当前AR

    4 不要在C++中使用setjmp和longjmp

    因为,longjmp的时候,不保证局部对象析构函数的调用

    longjmp()跳转前局部对象可能并不会析构(g++),也可能析构(VC++),C++标准对此并无明确要求。这种依赖于具体编译器版本的代码是应该避免的。

    而C++本身的throw关键字,却能严格保证局部对象构造和析构的成对调用。

    5 辩证看待异常处理

    已经存在大量没有严格使用异常处理C++函数库和类库,兼容的C库更是没有异常的概念,历史的包袱让C++很难完全采用异常处理。在这个方面,Java和C#从头开始,重要的库都实现了标准的异常处理规范,完全采用异常机制切实可行。

    有趣的是C++11在标准中删除了异常规范,而且添加了 noexcept关键字来声明一个函数不会抛出异常,可见异常并不是那么受欢迎。

    然而,C++的STL广泛使用异常,所以实际上使用了STL的C++程序是不可能禁用异常的,要是没有了STL,C++又有什么优势了呢?C++在不断的矛盾冲突中向前发展者。

  • 相关阅读:
    事务之三:编程式事务、声明式事务(XML配置事务、注解实现事务)
    file的getPath getAbsolutePath和getCanonicalPath的不同
    处理 JSON null 和空数组及对象
    Eclipse快捷键大全(转载)
    Annotation之三:自定义注解示例,利用反射进行解析
    Annotation之二:@Inherited注解继承情况
    innodb事务日志详解
    事务之二:spring事务(事务管理方式,事务5隔离级别,7个事务传播行为,spring事务回滚条件)
    Java 数组的三种创建方法,数组拷贝方法
    Eclipse 远程调试
  • 原文地址:https://www.cnblogs.com/charlesblc/p/6500961.html
Copyright © 2011-2022 走看看