【问题标题】:portable way to deal with 64/32 bit time_t处理 64/32 位 time_t 的便携方式
【发布时间】:2011-01-28 20:57:20
【问题描述】:

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

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

【问题讨论】:

标签: c portability 32bit-64bit


【解决方案1】:

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

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

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

【讨论】:

  • 这对我来说似乎一直是最干净的方法。很遗憾printf 没有包含time_t 值的格式说明符,即使它只是来自strftime%c 行为。
  • 谢谢,我想我喜欢它,除了 time_t 是签名的;我可能会使用 int64_t。
  • %jdintmax_t 怎么样?
  • @JL2210 是的,这应该可行.. 虽然我 认为 "%" PRIdMAX 可能更便携。
【解决方案2】:

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

如果您确定您只在time_tint 的平台上运行,您可以转换为intmax_t(来自stdint.h)并使用PRIdMAX(来自@987654328)打印它@)。

【讨论】:

  • 现在,(在此答案之后 9 年),您可以使用 %jd 代替 PRIdMAX,如 snprintf(str, sizeof(str), "%jd", (intmax_t)i_am_a_time_t_var)
【解决方案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

【讨论】:

  • 轻微吹毛求疵;宏名称不能以数字开头。我可能会选择一个更像<inttypes.h> 名称的名称,而不会侵犯保留的名称空间(ISO/IEC 9899:2011 §7.31.6 以 PRI 或 SCN 开头的宏,以及小写字母或X 可以添加到<inttypes.h> 标头中定义的宏中)。
【解决方案4】:

对 Alok 的回答稍作调整,它已在 Windows 和 Linux 上签名,所以:

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

更干净。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-28
    • 2012-09-17
    • 2016-09-28
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    相关资源
    最近更新 更多