我注意到一些程序员将 unsigned long 用于 timeval 的 tv_sec 和 tv_usec [当他们复制或操作它们时],而它们被定义为简单的 long。
虽然这确实让我想知道为什么当时间通常向前时它们会被这样定义。
使用long int
这些变量将工作到2038年,之后tv_sec
将在 4 字节的机器上溢出long
。
The <sys/time.h> header shall define the timeval structure that includes at least the following members:
time_t tv_sec Seconds.
suseconds_t tv_usec Microseconds.
您应该注意到使用time_t
type 代替long
,但在某些系统上它也是 32 位表示,而在其他系统上甚至有 64 位表示。为了避免溢出,time_t
可能会被改为一个无符号的 32 位整数或一个 64 位的整数。
这就是为什么有些人使用unsigned long
,因为它将停止溢出直到 2100 年+。您应该改用该time_t
类型,并且您不需要考虑您的程序应该在未来运行多长时间。
tv_sec
有类型time_t
。tv_usec
具有 type long
,并且需要签名,因为在tv_usec
减去timeval
值以计算时间间隔时(平均 50% 的时间)会得到负面结果,并且您必须检测到这一点并将其转换为从tv_sec
字段中借用。标准 (POSIX) 可以改为将类型设置为无符号并要求您提前检测包装,但它没有,可能是因为这将更难使用并且与现有做法相矛盾。
范围方面也没有理由tv_usec
无符号,因为它真正需要能够表示的最大范围是 -999999 到 1999998 (或者如果你想在重整化之前累积几个加法/减法,则为数倍)。
当 unix 时间被发明时,负时间可能是有意义的。就像,AT&T 需要足够的时间戳来记录 1960 年代发生的事情。
至于微秒,如果你减去两个值,你可以用带符号的值变成负数,用无符号的值变成 4+十亿。与 0 相比似乎更直观。