见了鬼了,静态库RELEASE版本不能try,catch?

ringphone 2007-07-11 10:36:49
怕不经意间改动了什么东西,特地新建一个静态库,写了个函数产生异常:

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函数内部的异常捕获无效,照此情况,那我岂不是无法写出安全的静态库了?大家碰到过这种情况吗?

...全文
949 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
sms88 2007-07-11
  • 打赏
  • 举报
回复
要改成异步模式try和catch才能在Release下工作,
搜索下怎么把编译选项改更异步模式,

改后很耗CPU和内存等资源就是
jasonshark 2007-07-11
  • 打赏
  • 举报
回复
我这里没代码可以做试验.
不过你可以把test()的函数签名改成 test() throw()试一下
总之我觉得这都是优化的结果
zdleek 2007-07-11
  • 打赏
  • 举报
回复
Release版本程序中能catch到异常,这个貌似本来就可以,和debug或者release无关
ringphone 2007-07-11
  • 打赏
  • 举报
回复
Release做了优化,只会检查代码中有显式throw的异常
----------------
你怎么解释我Release版本程序中能catch到异常?
jasonshark 2007-07-11
  • 打赏
  • 举报
回复
Release做了优化,只会检查代码中有显式throw的异常
ringphone 2007-07-11
  • 打赏
  • 举报
回复
要是能throw我就知道是有异常了,我还try干什么?
ringphone 2007-07-11
  • 打赏
  • 举报
回复
try
{
test();
}
catch(...)
{
MessageBox(GetFocus(),"程序捕获异常","test",MB_OK);
}
这段代码在Release版本的程序中是有效的,能捕获异常,但是在Release的静态库里无法捕获。
diudiuqqqq 2007-07-11
  • 打赏
  • 举报
回复
release是没有抛出异常的,直接报内存错
Bsq28 2007-07-11
  • 打赏
  • 举报
回复
要捕获异常是由throw 抛出的。release 的时候,没有调试信息了。 所以只能报内存不能读了。
  • 打赏
  • 举报
回复
你throw一个异常试试看。
jasonshark 2007-07-11
  • 打赏
  • 举报
回复
呵呵` 不客气~
ringphone 2007-07-11
  • 打赏
  • 举报
回复
终于知道了,VC在release版默认是同步异常,release版本不能捕获非法内存访问、除零等结构化异常,修改release的编译选项,加个/EHa就好了,谢谢楼上。
jasonshark 2007-07-11
  • 打赏
  • 举报
回复
也就是说, 在default的情况下,Compiler不去掉你的try...catch的条件是这段代码有显式的throw或函数调用, 其实这里还有个条件,就是函数不是nothrow的
jasonshark 2007-07-11
  • 打赏
  • 举报
回复
厄..你还是没找到根本原因...
下面是从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.
ringphone 2007-07-11
  • 打赏
  • 举报
回复
再写了段代码测试了一下,发现不仅仅是静态库的问题,而是函数内部不能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
0

RELEASE版本:
catched in main function

RELEASE版本在函数中try,catch无效,而只在main函数中有效?
WizardK 2007-07-11
  • 打赏
  • 举报
回复
学习学习
菜牛 2007-07-11
  • 打赏
  • 举报
回复
0xCDCDCDCD是DUBUG状态下变量初始化的值,DEBUG时用于判断无效指针。Release时这是一个有效值。

你一定要无效,这样:
LPRECT lprc = (LPRECT)NULL;
试试。
ringphone 2007-07-11
  • 打赏
  • 举报
回复
Release版本程序中能catch到异常,这个貌似本来就可以,和debug或者release无关
-----------------
是啊,现在问题就是为什么放到静态库就不起作用

16,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧