C++ try{} catch(…){} 与 Throw()的编译器优化

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()到你的函数中?

这是异常规范,只会出现在声明函数中,表示这个函数可能抛出任何类型的异常
void GetTag() throw(int);表示只抛出int类型异常
void GetTag() throw(int,char);表示抛出in,char类型异常
void GetTag() throw();表示不会抛出任何类型异常
void GetTag() throw(...);表示抛出任何类型异常

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(是的,假如你最后调用的函数可能抛出异常这就会有个问题了)。

本文转自http://ybxu-123.blog.163.com/blog/static/5947377020105833855326/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值