怕不经意间改动了什么东西,特地新建一个静态库,写了个函数产生异常:int test()
{
try
{
MessageBox(GetFocus(),"开始","test",MB_OK);
LPRECT lprc = (LPRECT)0xCDCDCDCD;
return lprc->left;
}
catch(...)
{
MessageBox(GetFocus(),"异常已捕获","test",MB_OK);
return 0;
}
}程序连接DEBUG版本的静态库,调用test运行正常,能弹出"异常已捕获"的信息,但是连接Release版本的静态库,调用test则无法捕获异常,系统报错内存0xCDCDCDCD不能读。奇怪的是我在调用程序test的时候加try,catch又能捕获异常,即:
try
{
test();
}
catch(...)
{
MessageBox(GetFocus(),"程序捕获异常","test",MB_OK);
}
是能捕获异常的,但这是程序捕获的,而不是在静态库里捕获。
不管程序是Debug还是Release版本,只要连接Release版本的静态库,test函数内部的异常捕获无效,照此情况,那我岂不是无法写出安全的静态库了?大家碰到过这种情况吗?

解决方案 »

  1.   

    要捕获异常是由throw 抛出的。release 的时候,没有调试信息了。 所以只能报内存不能读了。
      

  2.   

    release是没有抛出异常的,直接报内存错
      

  3.   

    try
    {
    test();
    }
    catch(...)
    {
    MessageBox(GetFocus(),"程序捕获异常","test",MB_OK);
    }
    这段代码在Release版本的程序中是有效的,能捕获异常,但是在Release的静态库里无法捕获。
      

  4.   

    要是能throw我就知道是有异常了,我还try干什么?
      

  5.   

    Release做了优化,只会检查代码中有显式throw的异常
      

  6.   

    Release做了优化,只会检查代码中有显式throw的异常
    ----------------
    你怎么解释我Release版本程序中能catch到异常?
      

  7.   

    Release版本程序中能catch到异常,这个貌似本来就可以,和debug或者release无关
      

  8.   

    我这里没代码可以做试验.
    不过你可以把test()的函数签名改成 test() throw()试一下
    总之我觉得这都是优化的结果
      

  9.   

    要改成异步模式try和catch才能在Release下工作,
    搜索下怎么把编译选项改更异步模式,改后很耗CPU和内存等资源就是
      

  10.   

    Release版本程序中能catch到异常,这个貌似本来就可以,和debug或者release无关
    -----------------
    是啊,现在问题就是为什么放到静态库就不起作用
      

  11.   

    0xCDCDCDCD是DUBUG状态下变量初始化的值,DEBUG时用于判断无效指针。Release时这是一个有效值。你一定要无效,这样:
    LPRECT  lprc  =  (LPRECT)NULL;  
    试试。
      

  12.   

    再写了段代码测试了一下,发现不仅仅是静态库的问题,而是函数内部不能catch:#include "windows.h"
    #include "stdio.h"int test1();void main()
    {
    try
    {
    printf("%d",test1());
    }
    catch(...)
    {
    printf("catched in main function\n");
    }
    }int test1()
    {
    try
    {
    LPRECT lprc = (LPRECT)0xCDCDCDCD;
    return lprc->left;
    }
    catch(...)
    {
    printf("catched\n");
    return 0;
    }
    }运行结果:
    DEBUG版本:
    catched
    0RELEASE版本:
    catched in main functionRELEASE版本在函数中try,catch无效,而只在main函数中有效?
      

  13.   

    厄..你还是没找到根本原因...
    下面是从MSDN上的 “Exception Handling: Default Synchronous Exception Model”摘抄的:
    In previous versions of Visual C++, the C++ exception handling mechanism supported asynchronous (hardware) exceptions by default. Under the asynchronous model, the compiler assumes any instruction may generate an exception.With the new synchronous exception model, now the default, exceptions can be thrown only with a throw statement. Therefore, the compiler can assume that exceptions happen only at a throw statement or at a function call. This model allows the compiler to eliminate the mechanics of tracking the lifetime of certain unwindable objects, and to significantly reduce the code size, if the objects' lifetimes do not overlap a function call or a throw statement. The two exception handling models, synchronous and asynchronous, are fully compatible and can be mixed in the same application.Catching hardware exceptions is still possible with the synchronous model. However, some of the unwindable objects in the function where the exception occurs may not get unwound, if the compiler judges their lifetime tracking mechanics to be unnecessary for the synchronous model.See the /GX and /EH compiler options for information on enabling exception handling.
      

  14.   

    也就是说, 在default的情况下,Compiler不去掉你的try...catch的条件是这段代码有显式的throw或函数调用, 其实这里还有个条件,就是函数不是nothrow的
      

  15.   

    终于知道了,VC在release版默认是同步异常,release版本不能捕获非法内存访问、除零等结构化异常,修改release的编译选项,加个/EHa就好了,谢谢楼上。