我搜索我的Linux盒子,看到这样的类型定义:
typedef __time_t time_t;
但是我找不到__time_t的定义。
我搜索我的Linux盒子,看到这样的类型定义:
typedef __time_t time_t;
但是我找不到__time_t的定义。
当前回答
[根]#猫时间
#include <time.h>
int main(int argc, char** argv)
{
time_t test;
return 0;
}
[root]# gcc -E time.c | grep __time_t .c
类型定义long int __time_t;
它在$INCDIR/bits/types.h中定义:
# 131 "/usr/include/bits/types.h" 3 4
# 1 "/usr/include/bits/typesizes.h" 1 3 4
# 132 "/usr/include/bits/types.h" 2 3 4
其他回答
在Visual Studio 2008中,它默认为__int64,除非你定义了_USE_32BIT_TIME_T。最好是假装不知道它的定义,因为它可以(也将)在不同平台之间改变。
答案肯定是特定于实现的。为了确定你的平台/编译器,只需要在你的代码中添加这个输出:
printf ("sizeof time_t is: %d\n", sizeof(time_t));
如果答案是4(32位),而你的数据意味着超过2038年,那么你有25年的时间来迁移你的代码。
如果你将数据存储为字符串,你的数据将会很好,即使它是一些简单的东西,如:
FILE *stream = [stream file pointer that you've opened correctly];
fprintf (stream, "%d\n", (int)time_t);
然后以同样的方式将其读入(fread, fscanf等读入int类型),就得到了纪元偏移时间。在. net中也存在类似的解决方案。我在Win和Linux系统之间传递64位的历元号没有问题(通过通信通道)。这会带来字节排序问题,但这是另一个主题。
为了回答paxdiablo的问题,我会说它打印了“19100”,因为程序是这样写的(我承认我自己在80年代也是这样写的):
time_t now;
struct tm local_date_time;
now = time(NULL);
// convert, then copy internal object to our object
memcpy (&local_date_time, localtime(&now), sizeof(local_date_time));
printf ("Year is: 19%02d\n", local_date_time.tm_year);
printf语句输出固定字符串“Year is: 19”,后面跟着一个由零填充的字符串“years since 1900”(tm->tm_year的定义)。在2000年,这个值显然是100。“%02d”填充两个零,但如果长度超过两个数字,则不会截断。
正确的方法是(只修改到最后一行):
printf ("Year is: %d\n", local_date_time.tm_year + 1900);
新问题:这种想法的基本原理是什么?
time_t只是8字节的类型定义(long long/__int64),所有编译器和操作系统都理解。在过去,它只用于长int(4字节),但现在不是了。如果你查看crtdef .h中的time_t,你会发现这两种实现,但操作系统将使用long long。
标准
威廉·布伦德尔引用了维基百科,但我更喜欢它来自马的嘴。
C99 N1256标准草案7.23.3 /3“时间组件”说:
声明的类型是size_t(在7.17中描述)clock_t和time_t,它们是能够表示时间的算术类型
6.2.5/18“类型”说明:
整型和浮动类型统称为算术类型。
POSIX 7 sys_types.h说:
[CX] time_t为整数类型。
其中[CX]定义为:
[CX] ISO C标准的扩展。
它是一种扩展,因为它提供了更强有力的保证:浮点数过时了。
gcc一行程序
不需要像Quassnoi提到的那样创建一个文件:
echo | gcc -E -xc -include 'time.h' - | grep time_t
在Ubuntu 15.10 GCC 5.2中,前两行是:
typedef long int __time_t;
typedef __time_t time_t;
命令分解和来自man gcc的一些引用:
-E:“预处理阶段结束后停止;不要正确运行编译器。” -xc:指定C语言,因为输入来自stdin,没有文件扩展名。 -include file: "处理文件,如果"#include "file""出现为主源文件的第一行。" -: stdin输入
在大多数传统平台上,它是一个32位有符号整数类型。然而,这会导致您的代码遭受2038年的错误。因此,现代C库应该将其定义为有符号的64位整型,这在几十亿年里是安全的。