博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++异常实现与longjmp, setjmp,栈指针EBP, Active Record
阅读量:6303 次
发布时间:2019-06-22

本文共 1585 字,大约阅读时间需要 5 分钟。

这篇讲的不错:

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

 

首先Active Record

 

然后EBP,ESP等指针

 

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

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

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

 

3 C语言中模拟异常处理

为了统一处理错误,C++,C#,等现代语言引入了异常处理机制。C里面模拟异常的代码大概如下:
#include 
#include
#include
jmp_buf jb;void f1(){ printf("进入f1()\n"); if(0/*正确执行*/){ } else { longjmp(jb,1); } printf("退出f1()\n");}void f2(){ printf("进入f2()\n"); if(1/*正确执行*/) { } else { longjmp(jb, 2); } printf("退出f2()\n");}int main(){ int r = setjmp(jb); if(r==0){ f1(); f2(); }else if(r==1){ printf("处理错误1\n"); exit(1); }else if(r==2){ printf("处理错误2\n"); 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++在不断的矛盾冲突中向前发展者。

 

你可能感兴趣的文章
《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(8)--- 主动器...
查看>>
状态码
查看>>
我的友情链接
查看>>
用sqlplus远程连接oracle命令
查看>>
多年一直想完善的自由行政审批流程组件【2002年PHP,2008年.NET,2010年完善数据设计、代码实现】...
查看>>
自动生成四则运算题目
查看>>
【翻译】使用新的Sencha Cmd 4命令app watch
查看>>
【前台】【单页跳转】整个项目实现单页面跳转,抛弃iframe
查看>>
因为你是前端程序员!
查看>>
数据库设计中的14个技巧
查看>>
Android学习系列(5)--App布局初探之简单模型
查看>>
git回退到某个历史版本
查看>>
ecshop
查看>>
HTML5基础(二)
查看>>
在GCE上安装Apache、tomcat等
查看>>
在Mac 系统下进行文件的显示和隐藏
查看>>
ue4(c++) 按钮中的文字居中的问题
查看>>
技能点
查看>>
读书笔记《乌合之众》
查看>>
Hadoop日记Day1---Hadoop介绍
查看>>