Debug过程中发现这样一个问题:在 tNow<m_last_active_time 的情况下,程序走进了 do-something 的分支。
//SYSM_TIME_INTERVAL_DISCONNECT_MULTI_CONNis 600
if(tNow - m_last_active_time > SYSM_TIME_INTERVAL_DISCONNECT_MULTI_CONN) {
do-something;
}
一般我们会认为这是不可能的,因为 SYSM_TIME_INTERVAL_DISCONNECT_MULTI_CONN 是个正值(600),但事实上这是可能的。
对于这里debug发现的问题,tNow是一个 unsigned long 类型input参数,大小为 1343973099,而m_last_active_time 也是个unsigned long 类型值,大小为 1343973100。在32位机器上运行下面的代码,都得到结果 4294967295,在64位机器上运行得到结果 18446744073709551615!由于没有最高位的符号位起作用,在赋予一个unsigned long类型变量一个负值的时候,如果我们还把它作为“无符号”类型值读取,就会出错。事实上,下面的代码中如果用 int(a-b),而不是 (a-b),那么,我们将得到正确的结果,-1。
#include <iostream>
using namespace std;
typedef unsigned long uint32;
int main(int argc, char* argv[])
{
uint32 a = 1343973099;
uint32 b = 1343973100;
cout << (a - b) << endl;
return 0;
}
总结上述内容,在做无符号整形数相减时要多个心眼,千万不要想当然的认为上述现象不可能发生。一个简单而保险的做法是,将减法改成加法,比如,将
if(tNow - m_last_active_time > SYSM_TIME_INTERVAL_DISCONNECT_MULTI_CONN)
改成
if(tNow > SYSM_TIME_INTERVAL_DISCONNECT_MULTI_CONN +m_last_active_time)