﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-日积月累-随笔分类-C/C++</title><link>http://www.cppblog.com/jsunhj/category/9790.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 11 Mar 2009 10:40:39 GMT</lastBuildDate><pubDate>Wed, 11 Mar 2009 10:40:39 GMT</pubDate><ttl>60</ttl><item><title>用非局部跳转设计异常体系</title><link>http://www.cppblog.com/jsunhj/archive/2009/03/11/76245.html</link><dc:creator>基础中的基础</dc:creator><author>基础中的基础</author><pubDate>Wed, 11 Mar 2009 09:20:00 GMT</pubDate><guid>http://www.cppblog.com/jsunhj/archive/2009/03/11/76245.html</guid><wfw:comment>http://www.cppblog.com/jsunhj/comments/76245.html</wfw:comment><comments>http://www.cppblog.com/jsunhj/archive/2009/03/11/76245.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jsunhj/comments/commentRss/76245.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jsunhj/services/trackbacks/76245.html</trackback:ping><description><![CDATA[用非局部跳转设计异常体系，下面是一段基础代码<br>
<div style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;1<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;&lt;setjmp.h&gt;<br>&nbsp;2<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>#include&nbsp;&lt;stdio.h&gt;<br>&nbsp;3<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br>&nbsp;4<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>void<br>&nbsp;5<img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>main()<br>&nbsp;6<img id=Codehighlighter1_52_604_Open_Image onclick="this.style.display='none'; Codehighlighter1_52_604_Open_Text.style.display='none'; Codehighlighter1_52_604_Closed_Image.style.display='inline'; Codehighlighter1_52_604_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_52_604_Closed_Image onclick="this.style.display='none'; Codehighlighter1_52_604_Closed_Text.style.display='none'; Codehighlighter1_52_604_Open_Image.style.display='inline'; Codehighlighter1_52_604_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><img src="http://www.cppblog.com/Images/dot.gif">{<br>&nbsp;7<img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;jmp_buf&nbsp;env;<br>&nbsp;8<img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jmpflag;<br>&nbsp;9<img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br>10<img id=Codehighlighter1_100_591_Open_Image onclick="this.style.display='none'; Codehighlighter1_100_591_Open_Text.style.display='none'; Codehighlighter1_100_591_Closed_Image.style.display='inline'; Codehighlighter1_100_591_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_100_591_Closed_Image onclick="this.style.display='none'; Codehighlighter1_100_591_Closed_Text.style.display='none'; Codehighlighter1_100_591_Open_Image.style.display='inline'; Codehighlighter1_100_591_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;do&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">{<br>11<img id=Codehighlighter1_144_275_Open_Image onclick="this.style.display='none'; Codehighlighter1_144_275_Open_Text.style.display='none'; Codehighlighter1_144_275_Closed_Image.style.display='inline'; Codehighlighter1_144_275_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_144_275_Closed_Image onclick="this.style.display='none'; Codehighlighter1_144_275_Closed_Text.style.display='none'; Codehighlighter1_144_275_Open_Image.style.display='inline'; Codehighlighter1_144_275_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;((jmpflag&nbsp;=&nbsp;setjmp(env))&nbsp;==&nbsp;0)&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">{&nbsp;/**//*&nbsp;try&nbsp;*/<br>12<img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("run&nbsp;normal&nbsp;block\n");<br>13<img id=Codehighlighter1_243_265_Open_Image onclick="this.style.display='none'; Codehighlighter1_243_265_Open_Text.style.display='none'; Codehighlighter1_243_265_Closed_Image.style.display='inline'; Codehighlighter1_243_265_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_243_265_Closed_Image onclick="this.style.display='none'; Codehighlighter1_243_265_Closed_Text.style.display='none'; Codehighlighter1_243_265_Open_Image.style.display='inline'; Codehighlighter1_243_265_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;longjmp(env,&nbsp;1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//*&nbsp;throw&nbsp;exception&nbsp;1&nbsp;*/<br>14<img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>15<img id=Codehighlighter1_308_399_Open_Image onclick="this.style.display='none'; Codehighlighter1_308_399_Open_Text.style.display='none'; Codehighlighter1_308_399_Closed_Image.style.display='inline'; Codehighlighter1_308_399_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_308_399_Closed_Image onclick="this.style.display='none'; Codehighlighter1_308_399_Closed_Text.style.display='none'; Codehighlighter1_308_399_Open_Image.style.display='inline'; Codehighlighter1_308_399_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if&nbsp;(jmpflag&nbsp;==&nbsp;1)&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//*&nbsp;catch&nbsp;(exception&nbsp;1)&nbsp;*/<br>16<img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("catch&nbsp;exception&nbsp;1\n");<br>17<img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>18<img id=Codehighlighter1_414_516_Open_Image onclick="this.style.display='none'; Codehighlighter1_414_516_Open_Text.style.display='none'; Codehighlighter1_414_516_Closed_Image.style.display='inline'; Codehighlighter1_414_516_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_414_516_Closed_Image onclick="this.style.display='none'; Codehighlighter1_414_516_Closed_Text.style.display='none'; Codehighlighter1_414_516_Open_Image.style.display='inline'; Codehighlighter1_414_516_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//*&nbsp;catch&nbsp;(<img src="http://www.cppblog.com/Images/dot.gif">),&nbsp;optional*/<br>19<img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("cathc&nbsp;all\n");<br>20<img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>21<img id=Codehighlighter1_526_585_Open_Image onclick="this.style.display='none'; Codehighlighter1_526_585_Open_Text.style.display='none'; Codehighlighter1_526_585_Closed_Image.style.display='inline'; Codehighlighter1_526_585_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_526_585_Closed_Image onclick="this.style.display='none'; Codehighlighter1_526_585_Closed_Text.style.display='none'; Codehighlighter1_526_585_Open_Image.style.display='inline'; Codehighlighter1_526_585_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**//*&nbsp;no&nbsp;catcher,&nbsp;use&nbsp;longjmp(prev_env,&nbsp;1)&nbsp;to&nbsp;prev&nbsp;jmp&nbsp;point&nbsp;*/<br>22<img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;while&nbsp;(0);<br>23<img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</div>
<br>上面的这段代码带来如下问题：<br>1. 为何要使用do...while (0)?<br>2. 使用异常码代表异常是否合适?<br>3. 当异常未被捕获时，如何丢给上一层?<br><br>1. 本意是用{}构造一个代码块以处理未捕获之异常，而用do...while(0)可以利于宏化。<br>2. 不合适，因为异常码的携带信息量太少，另外异常码不能为0。下面为了简单说明，我们还是用异常码作为设计。<br>3. 实际上就是如何保存上一层的跳转点的问题，这也是异常体系设计的重点。<br><br>一个简单的方案是保存一个异常栈；<br>* 每进入一层try，我们就压入一个当前异常帧；<br>* 每当一个被异常被捕获，弹出当前异常帧。<br>* 每当抛出或重新抛出一个异常时，使用栈顶的异常帧跳转到一个catch块。<br><br>为了能够跳转到一个catch块，一个异常帧至少包括信息：<br>1. 跳转点环境jmp_buf；注意代码13行，这里看起来longjmp(env,&nbsp;1);&nbsp; 由于我们需要设计成RAISE(1); 所以env不必指定;<br>&nbsp;&nbsp;&nbsp;那么env可直接来自局部变量，但是由于longjmp也可能是在一个函数中被调用，这时env必须可以全局访问，而用异常栈保存这个信息便可做到。<br>2. 跳转点的异常码；尽管抛出和捕获异常时都需要制定异常码，但是对于一个未捕获的异常，我们使用RERAISE()是不需要指定异常码的，因此，异常码必须保存于某处，异常栈便是个好地方。<br>3.&nbsp;上一级异常帧指针，这是支持栈结构必须的。<br>
<div style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">1<img id=Codehighlighter1_19_90_Open_Image onclick="this.style.display='none'; Codehighlighter1_19_90_Open_Text.style.display='none'; Codehighlighter1_19_90_Closed_Image.style.display='inline'; Codehighlighter1_19_90_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_19_90_Closed_Image onclick="this.style.display='none'; Codehighlighter1_19_90_Closed_Text.style.display='none'; Codehighlighter1_19_90_Open_Image.style.display='inline'; Codehighlighter1_19_90_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>struct&nbsp;exceptframe&nbsp;<img src="http://www.cppblog.com/Images/dot.gif">{<br>2<img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;jmp_buf&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;env;<br>3<img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ecode;<br>4<img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;exceptframe&nbsp;*prev;<br>5<img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>};</div>
<br>对于任何一个程序，同一时刻只有一个异常运行，换句话说，当一个异常尚未处理完毕，不应该有另一个异常抛出。基于这个原因，一个程序只需要一个异常栈即可,不同时刻，该异常栈服务于不同的异常。我们用一个全局变量代表异常栈<br>struct exceptframe *exceptstack; 
<img src ="http://www.cppblog.com/jsunhj/aggbug/76245.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jsunhj/" target="_blank">基础中的基础</a> 2009-03-11 17:20 <a href="http://www.cppblog.com/jsunhj/archive/2009/03/11/76245.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>