在Huihoo的ACE论坛中,有一网友问到为什么ACE_Time_Value的秒数在Debug版本少一秒,而
在Release版本上“正常”。经过对其代码的复读以及对ACE的跟踪,发现原来是编码不规范犯
下的一个很严重的错误造成的。本文就讨论这一例子。
以下引用
1 /*
2 我写了个从年月日时分秒数值得到ACE_Time_Value结果的函数:
3 */
4 long s_get_ace_datetime(ACE_Time_Value & ace_datetime,
5 int year,
6 int month,
7 int day,
8 int hour,
9 int min,
10 int sec)
11 {
12 if(year<1970 || year>2038 || month<1 || month>12 || day<1 || day>31 ||
13 hour<0 || hour>23 || min<0 || min>59 || sec<0 || sec>59)
14 ACE_ERROR_RETURN((LM_ERROR,
15 ACE_TEXT("%I(日期时间参数溢出合理的习惯日期时间范围1970.1.2-2038.1.18)n")),-1);
16 timespec_t spec_t;
17 tm time_tm;
18 time_tm.tm_year=year-1900;
19 time_tm.tm_mon=month-1;
20 time_tm.tm_mday=day;
21 time_tm.tm_hour=hour;
22 time_tm.tm_min=min;
23 #if defined (ACE_NDEBUG)
24 time_tm.tm_sec=sec;
25 #else
26 time_tm.tm_sec=sec+1; //奇怪,当由各部分数量构造ACE_Time_Value时,debug编译时,秒的数量总是自动减1,在此要补上1
27 #endif
28 spec_t.tv_sec=mktime(&time_tm);
29 if(spec_t.tv_sec<0)
30 ACE_ERROR_RETURN((LM_ERROR,ACE_TEXT("%I(日期时间转化错误,得到<0的time_t,日期范围是1970.1.2-2038.1.18)n")),-1);
31 ace_datetime.set(spec_t);
32 return 0;
33 }
34 /*
35 我在VC++7.1上分别编译了Debug版本和Release版本,time_tm.tm_sec竟然会有一秒的差别,莫名其妙地影响了我的项目.
36 哪位高手知道为什么?
37 另外ACE_Time_Value的范围太小,ACE中是否有大日期时间范围的其它类封装?
38 */
以下是我的回贴:
你这个问题还真有趣,我跟踪了ACE相关代码后才发现,问题原来出在你写的函数中,病因是,使用未完全初始化的结构体变量
timespec_t spec_t;
后面加上语句
memset(
&spec_t
,0,sizeof(timespec_t));
即可
局部变量 spec_t 在debug时,各字段均被初始化为0xCCCCCCCC,它是一个负数
在下面的操作中,只修改了tv_sec,而tv_nsec 仍为一个负数
spec_t.tv_sec=mktime(
&time_tm
);
ACE_Time_Value::normalize()默默地为你作了规格化处理,就替你减去了一秒钟。
原代码更严重的错误在于:
原以为 Release版本是“正常”的,其实不然,而是Release隐藏了更严重的错误。
严重是因为它表现出错误的时候很随机,一旦产品发布,很难发现。
//
对象(结构体)timespec有两个公有属性
typedef
struct
timespec
{
time_t tv_sec;
//
Seconds
long
tv_nsec;
//
Nanoseconds, 十亿分之一秒
}
timespec_t;
在原代码16行
timespec_t spec_t;
构造了一个 timespec_t 临时对象spec_t后,debug版把它各字段初始化为 0xcccccccc,这使得问题一下子得于曝光.而Release版本, spec_t 为一个随机值. 本例程中,不允许 spec_t的tv_nsec为非0的任何数,为正常尽管看上去没有问题,但是这个对应的ACE_Time_Value的值也不可靠.在特定情况下可能产生重大事故.
C++编码规范:
初始化对象时要完全。
声明一个结构体后,如果要对其初始化,建议先把它设为0之后再作后续操作,养成这样一个习惯,就不会出现这样郁闷的事了。
原贴出处:
http://www.huihoo.com/forum/viewthread.php?tid=11016
mooyee