VS2008异常捕获不到的问题

VS2008异常捕获不到的问题

try{} catch(…){}

try{ } catch(…){ }来捕获C++中一些意想不到的异常,这种方法在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

{  

BYTE* pch ;  

pch = ( BYTE* )00001234 ;   //给予一个非法地址  

   

*pch = 6 ; //对非法地址赋值,会造成Access Violation 异常  

}  

__except( EXCEPTION_EXECUTE_HANDLER )  

{  

AfxMessageBox( \"catched\" ) ;  

但是用__try, __except块还有问题,就是这个不是C++标准,而是Windows平台特有的扩展。而且如果在使用过程中涉及局部对象析构函数的调用,则会出现C2712 的编译错误。那么还有没有别的办法呢?

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

throw ()

为什么要加一个throw()到你的函数中?

这是异常规范,只会出现在声明函数中,表示这个函数可能抛出任何类型的异常。

  1. void GetTag() throw(int);表示只抛出int类型异常
  2. void GetTag() throw(intchar);表示抛出inchar类型异常
  3. void GetTag() throw();表示不会抛出任何类型异常
  4. void GetTag() throw(...);表示抛出任何类型异常
  5. void GetTag() throw(int);表示只抛出int类型异常

并不表示一定会抛出异常,但是一旦抛出异常只会抛出int类型,如果抛出非int类型异常,调用unexsetpion()函数,退出程序。

假如你加一个throw()属性到你的永远不会抛出异常的函数中,编译器会非常聪明的知道代码的意图和决定优化方式。考虑下面的代码:

class MyClass

{

    size_t CalculateFoo()

    {

        :

        :

    };

    size_t MethodThatCannotThrow() throw()

    {

        return 100;

    };

    void ExampleMethod()

    {

        size_t foo, bar;

        try

        {

            foo = CalculateFoo();

            bar = foo * 100;

            MethodThatCannotThrow();

            printf("bar is %d", bar);

        }

        catch (...)

        {

        }

    }

};

当编译器看到这个带"throw()"属性代码的时候,编译能够优化这个"bar"变量,因为它知道从MethodThatCannotThrow()函数中不会抛出任何的异常。如果没有这个throw()属性,编译器必须创建这个"bar"变量,因为假如MethodThatCannotThrow抛出了一个异常,这个异常句柄可能会需要依靠这个bar变量。

另外,象prefast源代码分析工具能够(也会)用throw()注释去优化他们的错误检测能力----举个例子,假如你有一个try/catch而且所有调用的函数都已经标记了throw(),实际上你不需要这个try/catch(是的,假如你最后调用的函数可能抛出异常这就会有个问题了)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值