C语言 处理 64/32 位 time_t 的便携方式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2467418/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
portable way to deal with 64/32 bit time_t
提问by MK.
I have some code which is built both on Windows and Linux. Linux at this point is always 32bit but Windows is 32 and 64bit. 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 64bit 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?
我有一些在 Windows 和 Linux 上构建的代码。Linux 在这一点上总是 32 位,但 Windows 是 32 和 64 位。Windows 希望 time_t 为 64 位,而 Linux 仍为 32 位。我很好,除了在某些地方 time_t 值被转换为字符串。所以当 time_T 是 32 位时,它应该用 %d 来完成,当它是 64 位时用 %lld ......这样做的聪明方法是什么?另外:有什么想法可以找到将 time_t 传递给 printf 样式函数以解决此问题的所有位置吗?
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?
编辑:我想出了将 TT_FMT 声明为 "%d" 或 "%lld" 然后将我的 printfs 更改为 printf("time: %d, register: blah") 为 printf("time: " TT_FMT ", register :等等”)有更好的方法吗?我如何找到它们?
采纳答案by Alok Singhal
According to the C standard, time_tis an arithmetic type, "capable of representing times". So, it could be doublefor 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.)
根据 C 标准,time_t是一种算术类型,“能够表示时间”。所以,它可以是double例如。(Posix更明确地提到了这一点,并且还保证time()返回自 Epoch 以来的秒数——C 标准不保证后者。)
Maybe the cleanest solution is to convert the value to whatever type you want. You may want one of unsigned long longor unsigned long:
也许最干净的解决方案是将值转换为您想要的任何类型。您可能需要unsigned long long或 之一unsigned long:
printf("%llu\n", (unsigned long long)t);
回答by porges
I think the only truly portable way is to use strftimeto convert the time_tto a string.
我认为唯一真正可移植的方法是使用strftime将 转换time_t为字符串。
If you're sure that you're only operating on platforms where time_tis an int, you could cast to intmax_t(from stdint.h) and print it using PRIdMAX(from inttypes.h).
如果您确定您只在time_t是 an 的平台上操作int,您可以转换为intmax_t(from stdint.h) 并使用PRIdMAX(from inttypes.h)打印它。
回答by R Samuel Klatchko
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:
原因是虽然您主要想要十进制的第二个,但您可能经常想要十六进制(或者您可能想要前导 0)。通过只在那里使用修饰符,您可以轻松编写:
"%" TT_MOD "x" // in hex
"%08" TT_MOD "d" // left pad with 0's so the number is at least 8 digits
回答by BlackLight
My favourite way of handling with the issue is:
我最喜欢处理这个问题的方法是:
- Re-define
time_tand use the redefinedtime_teverywhere instead ofunsigned long longetc.:
- 重新定义
time_t并在time_t任何地方使用重新定义的而不是unsigned long long等:
#define time_t intmax_t /* Or unsigned long long int, int64_t etc. */
- Use
strftimeevery time that you want to convert the timestamp to a string instead of relying on format strings. Format strings are unreliable, and overflow/underflow errors in format strings are often painful to debug, and hard to find while doing static analysis.
- 使用
strftime要时间戳转换为字符串,而不是依靠格式字符串每次。格式字符串不可靠,格式字符串中的上溢/下溢错误通常很难调试,并且在进行静态分析时很难找到。
A time will come however when most of the Unix system and compilers out there must converge towards a 64-bit time_t. At least, I hope that that time comes before 2038.
然而,当大多数 Unix 系统和编译器必须向 64 位time_t. 至少,我希望那个时间在 2038 年之前到来。
回答by ericcurtin
Slight adjustment on Alok's answer, it's signed on both Windows and Linux, so:
对 Alok 的回答稍作调整,它在 Windows 和 Linux 上都已签名,因此:
printf("%lld\n", t);
is cleaner.
更干净。

