paip.c++ gcc 不能捕获exception异常的解决

作者Attilax ,  EMAIL:1466519819@qq.com 
来源:attilax的专栏
地址:http://blog.csdn.net/attilax

现象:

不能捕获 "index out of range", 下标越界异常...经过测试,只能捕获手动throw出来的异常..使用windows的__try   ____except,,QT 的QT_try QT_catch 都是不行..

原因"

c++标准  try, catch, throw是C++标准里的语法,标准只要求try catch捕获throw出来的异常,并不要求捕获系统异常(如被0除,段错误,CPU异常等)。从C++层面来说,不要期望try, catch能捕获系统异常。
GCC所实现的C++异常处理框架中,它的catch(…)语法,并不能捕获系统异常。因此,这给C++中异常处理的良好运用打了大大的折扣;不同类型的系统异常等。所以Linux操作系统上的gcc编译的程序中,它只能捕获程序中,曾经被自己显式地throw出来的异常,而对于系统异常,catch block是毫无办法的。

解决:
///
a.windows系统,调用.Using a Vectored Exception Handler..SEH机制来解决.比较麻烦.
b.linux系统,信号来调用...比较麻烦.
c.自己多加判断,正则表达式是个好东西..

异常的类型:
//
分为手动throw出来的异常..可以捕获..
系统异常(如被0除,段错误,CPU异常等)

别的资料.
//
ry{} catch(…){}
以前都是用try{} catch(…){}来捕获C++中一些意想不到的异常, 今天看了Winhack的帖子才知道,这种方法在VC中其实是靠不住的。例如下面的代码:

try
{
BYTE* pch ;
pch = ( BYTE* )00001234 ;   //给予一个非法地址
*pch = 6 ; //对非法地址赋值,会造成Access Violation 异常
}
catch(...)
{
AfxMessageBox( "catched" ) ;
}
这段代码在debug下没有问题,异常会被捕获,会弹出”catched”的消息框。 但在Release方式下如果选择了编译器代码优化选项,则VC编译器会去搜索try块中的代码, 如果没有找到throw代码, 他就会认为try catch结构是多余的, 给优化掉。 这样造成在Release模式下,上述代码中的异常不能被捕获,从而迫使程序弹出错误提示框退出。

那么能否在release代码优化状态下捕获这个异常呢, 答案是有的。 就是__try, __except结构, 上述代码如果改成如下代码异常即可捕获。

__try

当然有, 就是仍然使用C++标准的try{}catch(..){}, 但在编译命令行中加入 /EHa 的参数。这样VC编译器不会把try catch模块给优化掉了。

找到一篇比较好的英文文章谈这个问

那么C++标准中对于这种同一个程序有不同的运行结果有何解释呢?这里需要注意的是,window2000系统下catch(…)能捕获住系统异常, 这完全是它自己的扩展。在C++标准中并没有要求到这一点,它只规定catch(…)必须能捕获程序中所有通过throw语句抛出的异常。因此上面的这个 程序在linux系统下的运行结果也完全是符合C++标准的。虽然大家也必须承认window2000系统下对C++异常处理模型的这种扩展确实是一个很 不错的完善,极大得提高了程序的安全性。

以上代码Debug版本运行不会弹对话框,因为"除零异常"了。而Release版本会弹,是因为变量a没有用到,被编译器优化掉了。若要使其不优化掉,把a使用printf函数打印出来。
可以去掉汇编实现的try,catch,看看编译器会不会报错!

最近看书时,看到异常处理中有try……except……
通常try -except是用来处理SEH异常的,而不是标准异常。具体参考下面的资料。
这两个都讲的很详细~
c++ try-except statement

在Windows系统中,使用VC2005编译的debug版本代码,try, catch能捕获到被0除异常,在网上查找下,说的是VC编译器对try, catch作了扩展,使用了Windows特有的结构化异常处理(tructured Exception Handling,SEH)机制,据说要在release版本中使用SEH,要选择编译选项/Eha,这我没有试过。
  摘抄一段话:SEH异常和C++异常有本质的区别, SEH是操作系统提供的异常处理技术, 在任何支持该操作系统的编程语言中, 都可以使用, 而C++异常处理只能在编写C++代码时使用。然而, 应当知道WINDOWS的VC++编译器是使用操作系统结构化异常来实现C++异常的.  也就是说, C++的try块在VC++下编译时, 会变成__try块,  C++的catch块会变成SEH的 __except块: catch测试则变成SEH异常过滤器, catch中的代码则变为__except中的代码. 事实上, C++的throw块, 在编译的时候也会变成SEH的RaiseException函数调用, 由c++异常变为SEH异常.(http://blog.csdn.net/ydbcsdn/article/details/5271755)
  在linux下,使用g++去编译时,try, catch是无法捕获被0除异常的,这我试过,不清楚是否有编译选项支持,即使不支持,也是合理的,因为C++标准并不要求支持。
  若想代码易于移植,或适用于多种系统,不要期望try,catch去捕获系统异常,若明确知道只使用于windows系统除外,但要记得打开编译选项/Eha,否则达不到你的期望。
  
  
  
参考:
第21集 Windows系列操作系统平台中所提供的异常处理机制:希赛网软件工程频道.htm
(imp)C++-MinGW能支持VC的__try的语法吗? - 德问 编程社交问答.htm
SEH异常,每个程序员都应当引起重视。 - CSDN论坛 - CSDN.NET.htm
imp...Using a Vectored Exception Handler (Windows).htmimp.
try?catch误区_zhoujie_liang_新浪博客.htm
imp....C语言的异常机制 setjump longjump函数【转】 - 红联Linux门户 - 中国领先的Linux技术网站 - 网站导航 - Linux通用技术 - Linux编程与内核.htm
imp,imp...C++-MinGW能支持VC的__try的语法吗? - 德问 编程社交问答.htm

//  QT_CATCH(...)
       // catch(...)
     //   catch(...)

paip.c++ gcc 不能捕获exception异常的解决相关推荐

  1. eclipse 中 Unhandled event loop exception异常的解决办法

    我的电脑上之前之前的Eclipse每次都会弹出这个问题"unhandled event loop exception",因为之前用的Java不多,所以以前一直是在忍受,今天因为要开 ...

  2. winform程序捕获全局异常,对错误信息写入日志并弹窗

    使用场景:在winform程序中如果没对方法进行try catch操作,若方法内出错,则整个程序报错并退出,如下图 如果程序已在客户手中,若没对错误的详细信息进行拍照,我们则不知道错误原因是什么.我们 ...

  3. java try catch嵌套_解析Java中未被捕获的异常以及try语句的嵌套使用

    Java未被捕获的异常 在你学习在程序中处理异常之前,看一看如果你不处理它们会有什么情况发生是很有好处的.下面的小程序包括一个故意导致被零除错误的表达式. class Exc0 { public st ...

  4. C# winform 捕获全局异常

    using System; using System.Collections.Generic; using System.Windows.Forms; using System.IO; namespa ...

  5. Android application捕获崩溃异常

    Java代码 个人笔记: 通用 application 1.收集所有 avtivity 用于彻底退出应用 2.捕获崩溃异常,保存错误日志,并重启应用 public class HKBaseApplic ...

  6. 加了try的情况下线程中抛出未捕获的异常

    一.问题描述 项目中线程中明明加了try catch 捕获异常,但是一启动就报未捕获的异常导致整个程序崩溃. 下面是windows中的错误日志. Application: 岗亭收费.exe Frame ...

  7. Django View使用装饰器捕获数据库连接异常

    "来不及解释了",直接上代码. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ...

  8. Java多线程:捕获线程异常

    你处理过多线程中的异常吗?如何捕获多线程中发生的异常?捕获子线程的异常与捕获当前线程的异常一样简单吗? 除了try catch.Java中还可以通过异常处理器UncaughtExceptionHand ...

  9. C语言signal()函数(通过设置一个函数(回调函数)来处理捕获到异常信号时需要执行的操作)

    文章目录 描述 声明 参数 返回值 实例 附加解释 背景知识:C语言中signal函数简介及使用 描述 C 库函数 void (*signal(int sig, void (*func)(int))) ...

  10. Java未被捕获的异常

    在你学习在程序中处理异常之前,看一看如果你不处理它们会有什么情况发生是很有好处的.下面的小程序包括一个故意导致被零除错误的表达式. class Exc0 { public static void ma ...

最新文章

  1. dnscapy使用——本质上是建立ssh的代理(通过dns tunnel)
  2. 编程之美---点是否在三角形内
  3. Eclipse VIM
  4. 数据中心基础设施管理的演进
  5. 【NLP】四万字全面详解 | 深度学习中的注意力机制(二)
  6. 使用WordPress的Kyma plugin同Kyma断开连接的实现
  7. 常见 Java 字节码 指令 助记符
  8. css table嵌套内部table不受外部影响_HTML+CSS网页一揽子(4)
  9. Oracle实用技巧
  10. linux关机命令_Linux基于centOS 7.6常见的Linux命令
  11. 他不怕被拒绝_不会敬酒很吃亏,送你五个敬酒词的模版,再也不怕劝酒了
  12. TypeError: keys must be str, int, float, bool or None, not tuple,解决 python 中 json 保存不了字典键值为 元组 的问题
  13. java,类的构造方法
  14. 从输入url到页面展现发生了什么?
  15. Android中的PackageManager
  16. 【驱动详解】如何理解驱动程序
  17. 重磅 | 死磕 Elasticsearch 方法论认知清单(2021年国庆更新版)
  18. Multiplier和Finger的区别和优劣讨论
  19. [源码解析] 机器学习参数服务器 Paracel (1)-----总体架构
  20. Python爬取安居客新房信息

热门文章

  1. BAT会看上哪样的中小公司程序员? 1
  2. Postgresql、MySQL相关的四种索引类型:B-Tree,Hash,Gist,GIN
  3. 移动app设计公司流程—APP设计需求分析规范
  4. java 重定向和转发的区别
  5. 演练Ext JS 4.2自定义主题
  6. 让划动 listview时 没有黑色背景
  7. 【笔记】FWT 快速沃尔什变换
  8. 【洛谷】【treap/堆】P2073 送花
  9. 《Java 多线程编程核心技术》- 笔记
  10. [Js-Java SE]文件/文件夹复制(递归)