深度剖析C++编译器怎样实现异常处理

由于C++编译器装程序太多,此处无法上传,所以大家有communitysever的可以从里面获得然后反编译为自己所用,没有的就到网络上搜下吧,有许多资源呢!下面进行详细说明。

站在用户的角度思考问题,与客户深入沟通,找到嵊泗网站设计与嵊泗网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:网站设计、成都做网站、企业官网、英文网站、手机端网站、网站推广、域名与空间、虚拟主机、企业邮箱。业务覆盖嵊泗地区。

与理则是一个极好的替代解决方案。它将正常代码 和错误处理代码清晰的划分开来,程序变得非常干净并且容易维护。本文讨论了编译器如何实现异常处理。我将假定你已经熟悉C++编译器处理的语法和机制。本文还提供 了一个用于VC++的异常处理库,要用库中的处理程序替换掉VC++提供的那个,你只需要调用下面这个函数:

 
 
 
  1. struct EXCEPTION_REGISTRATION  
  2. {  
  3.     EXCEPTION_REGISTRATION* prev;  
  4.     DWORD handler;  
  5. };  

之后,程序中的所有异常,从它们被抛出到堆栈展开(stack unwinding),再到调用catch块,***到程序恢复正常运行,都将由我的异常处理库来管理。
    与其它C++特性一样,C++标准并没有规定编译器应该如何来实现异常处理。这意味着每一个编译器的提供商都可以用它们认为恰当的方式来实现它。下面我会 描述一下VC++是怎么做的,但即使你使用其它的编译器或操作系统①,本文也应该会是一篇很好的学习材料。VC++的实现方式是以windows系统的结 构化异常处理(SEH)②为基础的。

 
 
 
  1. struct EXCEPTION_REGISTRATION  
  2. {  
  3.     EXCEPTION_REGISTRATION* prev;  
  4.     DWORD handler;  
  5. };  

在本文的讨论中,我认为异常或者是被明确的抛出的,或者是由于除零溢出、空指针访问等引起的。当它发生时会产生一个中断,接下来控制权就会传递到操作系统 的手中。操作系统将调用异常处理程序,C++编译器异常发生位置开始的函数调用序列,进行堆栈展开和控制权转移。Windows定义了结构 "EXCEPTION_REGISTRATION",使我们能够向操作系统注册自己的异常处理程序。

 
 
 
  1. #include   
  2. #include   
  3.  
  4. using std::cout;   
  5. using std::endl;   
  6.  
  7. struct EXCEPTION_REGISTRATION   
  8. {   
  9.     EXCEPTION_REGISTRATION* prev;   
  10.     DWORD handler;   
  11. };   
  12.  
  13. EXCEPTION_DISPOSITION myHandler(   
  14.     _EXCEPTION_RECORD *ExcRecord,   
  15.     void * EstablisherFrame,   
  16.     _CONTEXT *ContextRecord,   
  17.     void * DispatcherContext)   
  18. {   
  19.     cout << "In the exception handler" << endl;   
  20.     cout << "Just a demo. exiting..." << endl;   
  21.     exit(0);   
  22.     return ExceptionContinueExecution; //不会运行到这   
  23. }   
  24.  
  25. int  g_div = 0;   
  26.  
  27. void bar()   
  28. {   
  29.     //初始化一个EXCEPTION_REGISTRATION结构   
  30.     EXCEPTION_REGISTRATION reg, *preg = ®    
  31.     reg.handler = (DWORD)myHandler;   
  32.  
  33.     //取得当前异常处理链的"头"   
  34.     DWORD prev;   
  35.     _asm   
  36.     {   
  37.         mov EAX, FS:[0]   
  38.         mov prev, EAX   
  39.     }   
  40.     reg.prev = (EXCEPTION_REGISTRATION*) prev;   
  41.  
  42.     //注册!   
  43.     _asm   
  44.     {   
  45.         mov EAX, preg   
  46.         mov FS:[0], EAX   
  47.     }   
  48.  
  49.     //产生一个异常   
  50.     int  j = 10 / g_div;  //异常,除零溢出   
  51. }   
  52.  
  53. int  main()   
  54. {   
  55.     bar();   
  56.     return 0;   
  57. }   
  58.  
  59. /*-------输出-------------------   
  60. In the exception handler   
  61. Just a demo. exiting...  

C++编译器用于建立一个EXCEPTION_REGISTRATION结构的链表,每次注册新的EXCEPTION_REGISTRATION时,我们都要把原来注册的那个的地址存到prev中。 那么,那个异常回调函数长什么样呢?在excpt.h中,windows定义了它的原形: 注意EXCEPTION_REGISTRATION必须定义在栈上,并且必须位于比上一个结点更低的内存地址上,windows对此有严格要求,达不到的话,它就会立刻终止进程。

【编辑推荐】

  1. 有关C++优化代码问题详细说明
  2. 对C++库函数进行学习探索总结笔记
  3. 几分钟教会您使用Visual C++ 6.0设计程序
  4. 大致介绍C++语言相关使用及其错误修改
  5. 有关C++优化代码问题详细说明

当前名称:深度剖析C++编译器怎样实现异常处理
转载注明:http://www.shufengxianlan.com/qtweb/news44/74294.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联