在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