Подтвердить что ты не робот

Есть ли способ получить 64-битный time_t в 32-разрядной программе в Linux?

В Windows я могу позвонить:

_time32(__time32_t); // to get 32bit time_t
_time64(__time64_t); // to get 64bit time_t

(как в 32, так и в 64-битных программах)

Есть ли способ сделать это в Linux (компиляция с GCC)?

4b9b3361

Ответ 1

По-видимому, нет, это невозможно. Во-первых, в 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-битное значение, это ничего не изменит.

Вы можете привязать свое приложение к ядру, но я не думаю, что это даже стоит того.

Ответ 2

Функция time64()/time32() включена в стандартные библиотеки.

Определения time32_t/time64_t не рассматриваются в стандартных заголовках.

time_t определяется как time.h как typedef __time_t time_t;

Следуя длинной цепочке переопределений, вы обнаружите, что __time_t определяется как 32 бит на 32-битных машинах и 64-битных на 64-битных машинах.

Ответ 3

Если вам это действительно нужно, почему бы не опрокинуть свой собственный?

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.