#include <stdio.h>
#include <time.h>
int main()
{
printf("Size of time_t is %lu bytes.\n", sizeof(time_t));
time_t biggest = 0x7fffffffffffffff; // line 1
printf("time_t's wrap around will be a second after %s.\n", asctime(gmtime(&biggest)) );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在time.h中,这是time_t的定义吗?
typedef __darwin_time_t time_t
Run Code Online (Sandbox Code Playgroud)
怎么解释呢?由于我不知道,我使用sizeof函数来查找time_t = 8个字节.
为什么第1行会给出错误呢?我收到了这个错误
Segmentation fault: 11
Run Code Online (Sandbox Code Playgroud)
您的呼叫gmtime()可能正在返回NULL(它在我的Mac OS X系统上).将此值传递给时asctime(),会出现异常(因为它需要非NULL指针).
并非所有time_t值都可以用a表示struct tm,这就是为什么在这种情况下gmtime()返回NULL.
我查看了 Linux 头文件,发现了以下内容:
/usr/include/time.h:
typedef __time_t time_t;
/usr/include/bits/types.h:
__STD_TYPE __TIME_T_TYPE __time_t
/usr/include/bits/typesizes.h
#define __TIME_T_TYPE __SLONGWORD_TYPE
/usr/include/bits/types.h:
#define __SLONGWORD_TYPE long int
Run Code Online (Sandbox Code Playgroud)
所以大小time_t为long int。在 64 位机器上,您可能会得到 8 个字节。然后我发现在我的 32 位 FreeBSD 上,它看起来像这样:
/usr/include/machine/_types.h:
typedef __int32_t __time_t;
Run Code Online (Sandbox Code Playgroud)
所以大小是32位。
尽管 time_t 的大小为 8,但在 64 位平台上,实现定义的限制硬编码到运行时中,不能超过。当超出这些限制时,gmtime 将返回 NULL 并设置 errno 以指示错误的性质。您的代码无法检查从 gmtime 返回的 NULL,因此当 asctime 尝试取消引用该空指针时失败。这是您在使用惯用 C 而不检查可能失败的函数的返回值时所面临的风险。
当传递 32535291600 时,Windows 10 上的 Microsoft C gmtime 返回 NULL,errno 设置为 EINVAL。尽管人们可能认为理论上的最大限制应该是 LLONG_MAX。Microsoft 明确将限制设置为 _MAX__TIME64_T + _MAX_LOCAL_TIME。
来自 Microsoft Visual Studio 2010 CRT 源中的 ctime.h:
#define _MAX__TIME64_T 0x793406fffi64 /* number of seconds from 00:00:00, 01/01/1970 UTC to 23:59:59. 12/31/3000 UTC */
Run Code Online (Sandbox Code Playgroud)
Apple 的 gmtime 函数在传递 67768036191676800 时返回 NULL 并且将 errno 设置为 EOVERFLOW。Apple 实现始终表现出未定义的行为,其中 asctime() 返回年份中超过 4 位数字的字符串,因为 C 标准要求该函数不再返回超过 26 个字符。
的底层类型time_t可以是任何类型。这很大程度上取决于您的系统。请参考类似问题:time_t 是什么原始数据类型?。
线程中有一个指向sys/types.h描述的链接,其中指出
time_t 和clock_t 应为整数或实数浮点类型。
另一个很好的答案的链接:/sf/answers/32990121/