便携式处理64/32位time_t的方法

时间:2010-03-18 03:39:01

标签: c portability 32bit-64bit

我有一些在Windows和Linux上构建的代码。此时Linux总是32位,但Windows是32位和64位。 Windows希望time_t为64位,而Linux仍然将其作为32位。我很好,除了在某些地方time_t值转换为字符串。所以当time_T是32位时,它应该用%d完成,当它是64位时用%lld ...这样做的聪明方法是什么?另外:任何想法如何找到所有将time_t传递给printf样式函数以解决此问题的地方?

编辑: 我想出了将TT_FMT声明为“%d”或“%lld”,然后将我的printfs更改为 printf(“time:%d,register:blah”)为printf(“time:”TT_FMT“,注册:blah”) 有没有更好的办法?我如何找到它们?

5 个答案:

答案 0 :(得分:11)

根据C标准,time_t是算术类型,“能够表示时间”。因此,它可以是double。 (Posix mentions this more explicitly,并且还保证time()返回自Epoch以来的秒数 - 后者不受C标准的保证。)

也许最干净的解决方案是将值转换为您想要的任何类型。您可能需要unsigned long longunsigned long之一:

printf("%llu\n", (unsigned long long)t);

答案 1 :(得分:7)

我认为唯一真正可移植的方法是使用strftimetime_t转换为字符串。

如果您确定自己仅在time_tint的平台上投放,则可以转为intmax_t(来自stdint.h)并打印使用PRIdMAX(来自inttypes.h)。

答案 2 :(得分:3)

如果你想使用宏指示符,我会推荐一个小调整。而不是封装整个说明符,只封装修饰符:

#ifdef 64_BIT_TIME
  #define TT_MOD "ll"
#else
  #define TT_MOD ""
#endif

然后像这样使用它:

printf("current time in seconds is: %" TT_MOD "u", time(0));

原因在于,当你主要想要十进制的十进制时,你经常需要十六进制(或者你想要领先0)。只需要在那里使用修饰符,就可以轻松编写:

"%" TT_MOD "x"   // in hex
"%08" TT_MOD "d"  // left pad with 0's so the number is at least 8 digits

答案 3 :(得分:1)

我最喜欢的处理问题的方法是:

  1. 重新定义time_t并在各处使用重新定义的time_t而不是unsigned long long等。
#define  time_t  intmax_t  /* Or unsigned long long int, int64_t etc. */
  1. 每次要将时间戳转换为字符串而不是依赖格式字符串时,请使用strftime。格式字符串不可靠,格式字符串中的上溢/下溢错误通常很难调试,并且在进行静态分析时很难发现。

然而,当大多数Unix系统和那里的编译器必须收敛到64位time_t时,将会到来。至少我希望那个时间到2038年。

答案 4 :(得分:0)

对Alok的答案稍作调整,它已在Windows和Linux上签名,因此:

printf("%lld\n", t);

更干净。