unsigned整型数相减要小心

Debug过程中发现这样一个问题:在 tNow < m_last_active_time 的情况下,程序走进了 do-something 的分支。

//SYSM_TIME_INTERVAL_DISCONNECT_MULTI_CONN is 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)


你可能感兴趣的:(input)