处理 64/32 位 time_t 的可移植方式

发布于 2024-08-25 13:10:07 字数 649 浏览 6 评论 0原文

我有一些在 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 ,然后将我的 printf 更改

printf("time: %d, register: blah")

printf("time: " TT_FMT ", register: blah")

有更好的办法吗?我怎样才能找到它们呢?

I have some code which is built both on Windows and Linux. Linux at this point is always 32-bit but Windows is 32 and 64-bit. Windows wants to have time_t be 64-bit and Linux still has it as 32-bit. I'm fine with that, except in some places time_t values are converted to strings. So when time_t is 32-bit it should be done with %d and when it is 64-bit with %lld...

What is the smart way to do this? Also: any ideas how I may find all places where time_t's are passed to printf-style functions to address this issue?


Edit:
I came up with declaring TT_FMT as %d or %lld and then changing my printfs as in

printf("time: %d, register: blah")

to be

printf("time: " TT_FMT ", register: blah")

Is there a better way? And how do I find them all?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小忆控 2024-09-01 13:10:07

根据 C 标准,time_t 是一种算术类型,“能够表示时间”。因此,例如,它可以是double。 (Posix 更明确地提到了这一点,并且还保证time() 返回自纪元以来的秒数 - C 标准不保证后者。)

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

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

According to the C standard, time_t is an arithmetic type, "capable of representing times". So, it could be double for example. (Posix mentions this more explicitly, and also guarantees that time() returns the number of seconds since the Epoch—the latter is not guaranteed by the C standard.)

Maybe the cleanest solution is to convert the value to whatever type you want. You may want one of unsigned long long or unsigned long:

printf("%llu\n", (unsigned long long)t);
扛起拖把扫天下 2024-09-01 13:10:07

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

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

I think the only truly portable way is to use strftime to convert the time_t to a string.

If you're sure that you're only operating on platforms where time_t is an int, you could cast to intmax_t (from stdint.h) and print it using PRIdMAX (from inttypes.h).

一梦浮鱼 2024-09-01 13:10:07

如果您想使用宏说明符,我建议进行一项细微调整。不要封装整个说明符,而只封装修饰符:,

#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

If you want to go with the macro specifier, I would recommend one minor tweak. Instead of encapsulating the entire specifier, encapsulate just the modifier:

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

and then using it like this:

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

The reason why is that while you primarily want the second in decimal, every so often you may want hex (or perhaps you want leading 0's). By only having the modifier there, you can easily write:

"%" TT_MOD "x"   // in hex
"%08" TT_MOD "d"  // left pad with 0's so the number is at least 8 digits
断桥再见 2024-09-01 13:10:07

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

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

更干净。

Slight adjustment on Alok's answer, it's signed on both Windows and Linux, so:

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

is cleaner.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文