当前位置: 首页 > news >正文

网站开发开发优势做运营有前途吗

网站开发开发优势,做运营有前途吗,服务企业,做网站 图片侵权C 用异常使得可以将正常执行代码和出错处理区别开来。 比如一个栈#xff0c;其为空时#xff0c;调用其一个pop 函数#xff0c;接下来怎么办#xff1f; 栈本身并不知道该如何处理#xff0c;需要通知给其调用者#xff08;caller#xff09;#xff0c;因为只有调用… C 用异常使得可以将正常执行代码和出错处理区别开来。 比如一个栈其为空时调用其一个pop 函数接下来怎么办 栈本身并不知道该如何处理需要通知给其调用者caller因为只有调用者清楚接下来该怎么做。 异常就提供了一个很好机制。 但是异常需要操作系统编译器RTTI的特性支持。 下面围绕一个问题 “为什么析构函数不能抛出异常” 展开C中异常的实现。 Effective C 里面有一条”别让异常逃离析构函数“大意说是Dont do that otherwise the behavior is undefined. 这里讨论一下从异常的实现角度讨论一下为什么不要 1. 函数调用框架和SEH Structure Error Handling 程序 1 int widget( int a, int b)2 {3 return a b;4 }5 6  int bar(int a, int b)7 {8 int c widget(a, b);9 return c; 10 } 11 12  int foo( int a, int b) 13 { 14 int cbar(a, b); 15 return c; 16 } 17 18  int main() 19 { 20 foo( 1, 2); 21 } 其汇编代码 1 PUBLIC ?widgetYAHHHZ ; widget2 ; COMDAT ?widgetYAHHHZ3  _TEXT SEGMENT4 _a$ 8 ; size 45  _b$ 12 ; size 46  ?widgetYAHHHZ PROC ; widget, COMDAT7  8  ; 4 : {9  10  push ebp11  mov ebp, esp12  sub esp, 192 ; 000000c0H13  push ebx14  push esi15  push edi16  lea edi, DWORD PTR [ebp-192]17  mov ecx, 48 ; 00000030H18  mov eax, -858993460 ; ccccccccH19  rep stosd20 21  ; 5 : return a b;22  23  mov eax, DWORD PTR _a$[ebp]24  add eax, DWORD PTR _b$[ebp]25 26  ; 6 : }27  28  pop edi29  pop esi30  pop ebx31  mov esp, ebp32  pop ebp33  ret 034 ?widgetYAHHHZ ENDP ; widget35  _TEXT ENDS36 PUBLIC ?barYAHHHZ ; bar37  EXTRN __RTC_CheckEsp:PROC38  ; Function compile flags: /Odtp /RTCsu /ZI39 ; COMDAT ?barYAHHHZ40  _TEXT SEGMENT41 _c$ -8 ; size 442  _a$ 8 ; size 443  _b$ 12 ; size 444  ?barYAHHHZ PROC ; bar, COMDAT45  46  ; 9 : {47  48  push ebp49  mov ebp, esp50  sub esp, 204 ; 000000ccH51  push ebx52  push esi53  push edi54  lea edi, DWORD PTR [ebp-204]55  mov ecx, 51 ; 00000033H56  mov eax, -858993460 ; ccccccccH57  rep stosd58 59  ; 10 : int c widget(a, b);60  61  mov eax, DWORD PTR _b$[ebp]62  push eax63  mov ecx, DWORD PTR _a$[ebp]64  push ecx65  call ?widgetYAHHHZ ; widget66  add esp, 867  mov DWORD PTR _c$[ebp], eax68 69 ; 11 : return c;70 71 mov eax, DWORD PTR _c$[ebp]72 73 ; 12 : }74 75 pop edi76 pop esi77 pop ebx78 add esp, 204 ; 000000ccH79 cmp ebp, esp80 call __RTC_CheckEsp81 mov esp, ebp82 pop ebp83 ret 084 ?barYAHHHZ ENDP ; bar85 _TEXT ENDS86 PUBLIC ?fooYAHHHZ ; foo87 ; Function compile flags: /Odtp /RTCsu /ZI88 ; COMDAT ?fooYAHHHZ89 _TEXT SEGMENT90 _c$ -8 ; size 491 _a$ 8 ; size 492 _b$ 12 ; size 493 ?fooYAHHHZ PROC ; foo, COMDAT94 95 ; 15 : {96 97 push ebp98 mov ebp, esp99 sub esp, 204 ; 000000ccH 100 push ebx 101 push esi 102 push edi 103 lea edi, DWORD PTR [ebp-204] 104 mov ecx, 51 ; 00000033H 105 mov eax, -858993460 ; ccccccccH 106 rep stosd 107 108 ; 16 : int cbar(a, b); 109 110 mov eax, DWORD PTR _b$[ebp] 111 push eax 112 mov ecx, DWORD PTR _a$[ebp] 113 push ecx 114 call ?barYAHHHZ ; bar 115 add esp, 8 116 mov DWORD PTR _c$[ebp], eax 117 118 ; 17 : return c; 119 120 mov eax, DWORD PTR _c$[ebp] 121 122 ; 18 : } 123 124 pop edi 125 pop esi 126 pop ebx 127 add esp, 204 ; 000000ccH 128 cmp ebp, esp 129 call __RTC_CheckEsp 130 mov esp, ebp 131 pop ebp 132 ret 0 133 ?fooYAHHHZ ENDP ; foo 134 _TEXT ENDS 135 PUBLIC _main 136 ; Function compile flags: /Odtp /RTCsu /ZI 137 ; COMDAT _main 138 _TEXT SEGMENT 139 _main PROC ; COMDAT 140 141 ; 21 : { 142 143 push ebp 144 mov ebp, esp 145 sub esp, 192 ; 000000c0H 146 push ebx 147 push esi 148 push edi 149 lea edi, DWORD PTR [ebp-192] 150 mov ecx, 48 ; 00000030H 151 mov eax, -858993460 ; ccccccccH 152 rep stosd 153 154 ; 22 : 155 ; 23 : foo( 1, 2); 156 157 push 2 158 push 1 159 call ?fooYAHHHZ ; foo 160 add esp, 8 161 162 ; 24 : } 163 164 xor eax, eax 165 pop edi 166 pop esi 167 pop ebx 168 add esp, 192 ; 000000c0H 169 cmp ebp, esp 170 call __RTC_CheckEsp 171 mov esp, ebp 172 pop ebp 173 ret 0 174 _main ENDP 175 _TEXT ENDS 176 END 调用框架  2。  加入SEH 之后函数调用框架稍微修改一下 对每一个函数加入一个Exception_Registration 的链表链表头存放在FS:[0] 里面。当异常抛出时就去遍历该链表找到合适的catch 块。 对于每一个Exception_Registration 存放链表的上一个节点异常处理函数 Error Handler). 用来处理异常。 这些结构都是编译器加上的分别在函数调用的prologue 和epilogue 注册和注销 一个异常处理节点。 NOTE error handling 1. 当异常发生时系统得到控制权系统从FS:[0]寄存器取到异常处理链的头以及异常的类型 调用异常处理函数。异常函数是编译器生成的 2. 从链表头去匹配 异常类型和catch 块接收的类型。 这里用到RTTI 信息 3. unwind stack。这里需要析构已经创建的对象。 这里需要判断析构哪些对象这一步是编译器做的 4. 执行catch 块代码。 后返回到程序的正常代码即catch块下面的第一行代码。 可见在exception 找到对应的 Catche 块后 去栈展开unwind stack析构已有的对象后进入到Catch 块中。 问题是 程序怎么知道程序运行到哪里 哪些对象需要调用析构函数 这也是编译器做的对于每一个Catch 块其记录下如果该catch 块若被调用哪些对象需要被析构。 这有这么一张表。具体实现可以参见reference2. 3. 当析构抛出异常时接下来的故事。 实验1  Base 类的析构抛出异常 1 class Base2 {3 public:4 void fun() { throw 1; }5 ~Base() { throw 2; }6 };7 8 int main()9 { 10 try 11 { 12 Base base; 13 //base.fun(); 14 } 15 catch (...) 16 { 17 //cout get the catchendl; 18 } 19 } 运行没有问题。 实验2: 打开上面注释掉的第13行代码 //base.fun(); 再试运行结果呢 在debug 模式下弹出对话框 为什么呢 因为SEH 是一个链表链表头地址存在FS:[0] 的寄存器里面。 在实验2函数base.fun先抛出异常从FS:[0]开始向上遍历 SHL 节点匹配到catch 块。 找到代码里面为一个catch块再去展开栈调用base 的析构函数然而析构又抛出异常。 如果系统再去从SEL链表匹配会改变FS:[0]值这时候程序迷失了不知道下面该怎么什么 因为他已经丢掉了上一次异常链那个节点。 实验3如果析构函数的异常被处理呢 程序还会正常运行吗 1 class Base2 {3 public:4 void fun() { throw 1; }5 ~Base() 6 {7 try8 {9 throw 2; 10 } 11 catch (int e) 12 { 13 // do something 14 } 15 } 16 }; 17 18 int main() 19 { 20 try 21 { 22 Base base; 23 //base.fun(); 24 } 25 catch (...) 26 { 27 //cout get the catchendl; 28 } 29 } 的确可以运行。 因为析构抛出来的异常在到达上一层析构节点之前已经被别的catch 块给处理掉。那么当回到上一层异常函数时 其SEH 没有变程序可以继续执行。 这也许就是为什么C不支持异常中抛的异常。 4. 效率 当无异常抛出时其开销就是在函数调用的时候注册/注销 异常处理函数这些开销很小。 但是当异常抛出时其开销就大了编译异常链用RTTI比配类型调用析构但是比传统的那种返回值层层返回效率也不会太差。 带来好的好处是代码好维护减少出错处理的重复代码并且与逻辑代码分开。 权衡一下好处还是大大的:) 5. 总结一下流程 为了安全”析构函数尽可能的不要抛出异常“。 如果非抛不可语言也提供了方法就是自己的异常自己给吃掉。但是这种方法不提倡我们提倡有错早点报出来。 Note 1.同样还有一个问题”构造函数可以抛出异常么 为什么“ C 里面当构造函数抛出异常时其会调用构造函数里面已经创建对象的析构函数但是对以自己的析构函数没有调用就可能产生内存泄漏比如自己new 出来的内存没有释放。 有两个办法。在Catch 块里面释放已经申请的资源 或者 用智能指针把资源当做对象处理。 Delphi 里面当构造函数抛异常时在其执行Catch 代码前其先调用析构函数。 所以构造抛出异常是否调用析构函数不是取决于技术而是取决于语言的设计者。 2. 关于多线程异常是线程安全的。 对于每一个线程都有自己的 Thread Info/Environment Block. 维护自己的SEH结构。 Reference: 1.http://www.codeproject.com/KB/cpp/exceptionhandler.aspx 2.http://baiy.cn/doc/cpp/inside_exception.htm 3.http://www.mzwu.com/article.asp?id1469
http://wiki.neutronadmin.com/news/235870/

相关文章:

  • 兰州城建设计院网站门户网站建设的企业
  • 中国建设银行个人网站注册网站建设app
  • 电子商务网站建设与维护致谢词网站制作长沙
  • 公共场所建设网站网页设计html代码大全p
  • 网站建设合同需要缴纳印花税上海公司网站建设服务
  • 群晖ds1817做网站迷你主机做网站
  • 设计建设网站公司哪家好seo咨询茂名
  • 免费注册网站域名卷帘门怎么做网站
  • 建设个人博客网站百度云搜索引擎入口
  • 做网站第一步要干啥轻量级服务器wordpress
  • 网站建设都包含哪些内容秦皇岛做网站的公司有哪些
  • 虚拟空间的网站赚钱吗教育机构网站代码
  • 介绍自己做衣服的网站电子商务网络推广主要做什么
  • 公司需要做网站吗建网站合同
  • 招聘网站大全58同城h5网页版制作
  • 网站没有备案会被降权吗flash建网站教程
  • 会展网站建设h开头的网页设计软件
  • 常用ppt模板网站有关建设网站的英语文献
  • 企业网站制作公司合肥dede 汽车网站
  • 个人如何接网站建设订单预算有哪些网站做私活
  • 网站域名证书哪里获取推广链接让别人点击
  • 北京食药局网站年检怎么做青岛专业网站开发公司
  • 做网站需要哪些程序上海轨道交通建设查询网站
  • 做网站优化公司报价wordpress首页文章缩略图插件
  • 强化网站建设和管理网络优化工程师前景
  • 荆门市住房和城乡建设局网站有没有帮人做CAD的网站
  • 建站网哪个好青岛网站建设哪家更好
  • 吴家山网站建设公司湖南企业网站制作公司
  • 上海免费网站建设咨询品牌设计公司成都
  • 做公寓酒店跟网站合作有什么技巧济宁恒德建设有限公司网站