В Windows я могу позвонить:
_time32(__time32_t); // to get 32bit time_t
_time64(__time64_t); // to get 64bit time_t
(как в 32, так и в 64-битных программах)
Есть ли способ сделать это в Linux (компиляция с GCC)?
В Windows я могу позвонить:
_time32(__time32_t); // to get 32bit time_t
_time64(__time64_t); // to get 64bit time_t
(как в 32, так и в 64-битных программах)
Есть ли способ сделать это в Linux (компиляция с GCC)?
По-видимому, нет, это невозможно. Во-первых, в 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;
}
Системный вызов определяется как: (Источник)
SYSCALL_DEFINE1(time, time_t __user *, tloc)
{
time_t i = get_seconds();
// ...
return i;
}
Функция get_seconds()
возвращает unsigned long
, например: (Источник)
unsigned long get_seconds(void)
{
struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;
}
И timekeeper.xtime_sec
на самом деле является 64-битным: (Источник)
struct timekeeper {
// ...
/* Current CLOCK_REALTIME time in seconds */
u64 xtime_sec;
// ...
}
Теперь, если вы знаете свой C, вы знаете, что размер unsigned long
на самом деле зависит от реализации. На моей 64-битной машине здесь 64-бит; но на моей 32-битной машине здесь 32-бит. Возможно, это может быть 64-бит в 32-битной реализации, но нет гарантии.
С другой стороны, u64
всегда 64-бит, поэтому на самой базе ядро отслеживает время в 64-битном типе. Почему он затем возвращает это как unsigned long
, который не гарантирован на 64-битный длинный, находится вне меня.
В конце, даже если libc заставит time_t
удерживать 64-битное значение, это ничего не изменит.
Вы можете привязать свое приложение к ядру, но я не думаю, что это даже стоит того.
Функция time64()/time32()
включена в стандартные библиотеки.
Определения time32_t/time64_t
не рассматриваются в стандартных заголовках.
time_t
определяется как time.h
как typedef __time_t time_t
;
Следуя длинной цепочке переопределений, вы обнаружите, что __time_t
определяется как 32 бит на 32-битных машинах и 64-битных на 64-битных машинах.
Если вам это действительно нужно, почему бы не опрокинуть свой собственный?
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()
.
Если вы не заботитесь о переполнении, простой return time(NULL);
будет работать для обеих функций благодаря неявным числовым преобразованиям C.