zoukankan      html  css  js  c++  java
  • paip.c++ gcc 不能捕获exception异常的解决

    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(...)
  • 相关阅读:
    [导入]流失
    [导入]喜欢与爱
    [导入]毕业的大学生的100条忠告
    sql 实现从右边查询制定字符出现的位置
    [导入]毕业了
    gridview 实现多字段综合查询
    Java实现图片添加水印文字(左右下角)
    python安装win32api pywin32 后出现 ImportError: DLL load failed
    Asp.net mvc 速度优化 关注Yslow(1)
    WPF 3D中如何选择模型的一部分并维护模型
  • 原文地址:https://www.cnblogs.com/attilax/p/15199507.html
Copyright © 2011-2022 走看看