在Windows上,我可以致电:
_time32(__time32_t); // to get 32bit time_t
_time64(__time64_t); // to get 64bit time_t
(32位和64位程序)
在Linux中有没有办法(用GCC编译)?
答案 0 :(得分:12)
显然,不可能。对于初学者来说,Linux中只有一个time()
功能,没有time32()
或time64()
。
经过一段时间的搜索,我发现这不是libc的错,但罪魁祸首实际上就是内核。
为了让libc获取当前时间,它需要为它执行系统调用:(Source)
time_t time (t) time_t *t;
{
// ...
INTERNAL_SYSCALL_DECL (err);
time_t res = INTERNAL_SYSCALL (time, err, 1, NULL);
// ...
return res;
}
系统调用定义为:(Source)
SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
time_t i = get_seconds();
// ...
return i;
}
函数get_seconds()
返回unsigned long
,如下所示:(Source)
unsigned long get_seconds(void)
{
struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;
}
timekeeper.xtime_sec
实际上是64位:(Source)
struct timekeeper {
// ...
/* Current CLOCK_REALTIME time in seconds */
u64 xtime_sec;
// ...
}
现在,如果你知道你的C,你知道unsigned long
的大小实际上是依赖于实现的。在我的64位机器上,它是64位;但在我的32位机器上,这是32位。在某些32位实现中,可能可能是64位,但不能保证。
另一方面,u64
总是64位,因此在最基础上,内核会以64位类型跟踪时间。为什么然后它继续返回为unsigned long
,这不保证是64位长,超出了我。
最后,即使libc强制time_t
保持64位值,也不会改变它。
您可以将应用程序深入到内核中,但我认为它甚至不值得。
答案 1 :(得分:6)
标准库中不包含time64()/time32()
函数。
标准标题中未考虑time32_t/time64_t
定义。
time_t
被time.h
定义为typedef __time_t time_t
;
经过长链重新定义后,您会发现__time_t
在32位计算机上定义为32位,在64位计算机上定义为64位。
答案 2 :(得分:5)
上面的许多回答都说这是不可能的,但这完全是不正确的。当时 不可能,但人们已经talking about fixing it很多年了。最终,introduced to the Linux 5.1 kernel在32位平台上提供了64位时间支持,并增加了新的*time64
syscalls。查看this table,您会看到这些系统调用仅在32位平台上可用。现在,如果您正在为32位系统编写代码,则可以直接调用clock_gettime64
(从内联汇编程序或使用syscall()
的C语言)以获取当前时间
但是,此后,您将完全依靠自己。如果要获得完整的 userspace 支持,则必须在Linux 5.6或更高版本上以及musl 1.2+或glibc 2.32+。只需重建代码,您的time_t
就会变成64位长
所有用户空间都必须使用64位
time_t
进行编译,在即将发布的musl-1.2和glibc-2.32版本以及从linux-5.6或更高版本安装的内核头文件中都将支持该功能。需要直接移植使用系统调用接口的应用程序,以使用linux-5.1中添加的
time64
syscall代替现有的系统调用。这会影响futex()
和seccomp()
的大多数用户,以及具有自己的基于libc的运行时环境的编程语言。
更多信息
答案 3 :(得分:0)
如果你真的需要这个,为什么不自己推?
typedef int32_t my_time32;
typedef int64_t my_time64;
my_time32 get_mytime32() {
if (sizeof(time_t) == sizeof(my_time32))
return time(NULL);
else {
/* Check for overflow etc. here... */
return (my_time32)(time(NULL));
}
}
同样适用于get_mytime64()
。
如果您不关心溢出,由于C的隐式数字转换,简单的return time(NULL);
将适用于这两个函数。
答案 4 :(得分:0)
使用此库:https://github.com/evalEmpire/y2038
该项目的目标是为POSIX提供替代产品 time.h可以在具有32位time_t的机器上工作,但不能 遭受2038错误的困扰。这将使C程序员能够 2038安全-无需将其软件重写为新界面。 在仍然使用系统时区数据库的情况下执行此操作。