Chinaunix首页 | 论坛 | 博客
  • 博客访问: 283736
  • 博文数量: 41
  • 博客积分: 2630
  • 博客等级: 少校
  • 技术积分: 702
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-30 15:56
文章分类

全部博文(41)

文章存档

2012年(2)

2011年(2)

2010年(3)

2009年(26)

2008年(8)

我的朋友

分类: C/C++

2008-04-29 21:22:26

   项目要交付了,开始在Release下测试,发现导出挂掉了。
一直找不到原因,最后组长定位了错误:
ASSERT( database.OpenEx(sql, CDatabase::noOdbcDialog) );
原来如此,database.OpenEx(sql, CDatabase::noOdbcDialog)这句根本没有执行,哎,没经验,犯了低级错误。可以改为:

bool retval = database.OpenEx(sql, CDatabase::noOdbcDialog);
ASSERT(retval);

 
   后来看了点debug与release的比较,zz一下。
在使用VC开发软件的过程中,正当要享受那种兴奋的时候突然发现:release与debug运
行结果不一致,甚至出错,而release又不方便调试,真
的是当头一棒啊,可是疼归疼,问题总要解决,下面将讲述一下我的几点经验,看看是
不是其中之一:
1. 变量。
    大家都知道,debug跟release在初始化变量时所做的操作是不同的,debug是将每个字
节位都赋成0xcc(注1),而release的赋值近似于
随机(我想是直接从内存中分配的,没有初始化过)。这样就明确了,如果你的程序中的
某个变量没被初始化就被引用,就很有可能出现异常:
用作控制变量将导致流程导向不一致;用作数组下标将会使程序崩溃;更加可能是造成
其他变量的不准确而引起其他的错误。所以在声明变量
后马上对其初始化一个默认的值是最简单有效的办法,否则项目大了你找都没地方找。
代码存在错误在debug方式下可能会忽略而不被察觉到,
如debug方式下数组越界也大多不会出错,在release中就暴露出来了,这个找起来就比
较难了:( 还是自己多加注意吧
2. 自定义消息的消息参数。
    MFC为我们提供了很好的消息机制,更增加了自定义消息,好处我就不用多说了。这也
存在debug跟release的问题吗?答案是肯定的。
在自定义消息的函数体声明时,时常会看到这样的写法:afx_msg LRESULT OnMessageO
wn(); Debug情况下一般不会有任何问题,而当你在
Release下且多线程或进程间使用了消息传递时就会导致无效句柄之类的错误。导致这个
错误直接原因是消息体的参数没有添加,即应该写成:
afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam); (注2)
3. release模式下不出错,但debug模式下报错。
    这种情况下大多也是因为代码书写不正确引起的,查看MFC的源码,可以发现好多ASSE
RT的语句(断言),这个宏只是在debug模式下才
有效,那么就清楚了,release版不报错是忽略了错误而不是没有错误,这可能存在很大
的隐患,因为是Debug模式下,比较方便调试,好好的
检查自己的代码,再此就不多说了。
4. ASSERT, VERIFY, TRACE..........调试宏
    这种情况很容易解释。举个例子:请在VC下输入ASSERT然后选中按F12跳到宏定义的地
方,这里你就能够发现Debug中ASSERT要执行
AfxAssertFailedLine,而Release下的宏定义却为"#define ASSERT(f) ((void)0)"。所
以注意在这些调试宏的语句不要用程序相关变量如i++
写操作的语句。VERIFY是个例外,"#define VERIFY(f) ((void)(f))",即执行,这里的
作用就不多追究了,有兴趣可自己研究:)。
总结:
    Debug与Release不同的问题在刚开始编写代码时会经常发生,99%是因为你的代码书写
错误而导致的,所以不要动不动就说系统问题或
编译器问题,努力找找自己的原因才是根本。我从前就常常遇到这情况,经历过一次次
的教训后我就开始注意了,现在我所写过的代码我已经
好久没遇到这种问题了。下面是几个避免的方面,即使没有这种问题也应注意一下:
1. 注意变量的初始化,尤其是指针变量,数组变量的初始化(很大的情况下另作考虑了
)。
2. 自定义消息及其他声明的标准写法
3. 使用调试宏时使用后最好注释掉
4. 尽量使用try - catch(...)
5. 尽量使用模块,不但表达清楚而且方便调试。
阅读(1725) | 评论(0) | 转发(0) |
0

上一篇:JAVA-String源码学习

下一篇:GCC、GDB的学习

给主人留下些什么吧!~~