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

Почему "gmtime" берет указатель?

Согласно документации, struct tm *gmtime(const time_t *timer); должен преобразовать time_t, на который указывает timer, на время разбивки.

Теперь есть причина, по которой они решили сделать функцию вместо указателя time_t указателем на time_t?

Насколько я понимаю, time_t имеет арифметический тип и поэтому должен быть доступен для передачи напрямую (также я считаю разумным, что он поместился бы в long). Также существует какая-либо конкретная обработка указателя NULL (который мог мотивировать передачу указателя).

Есть ли что-то, что мне не хватает? Что-то еще актуальное сегодня?

4b9b3361

Ответ 1

Из того, что я видел, это скорее историческая причуда. Когда time.h был впервые введен и с ним функционирует как time, он использовал значение, которое не могло быть возвращено (например: no long int и т.д.). Стандарт определил неясный тип time_t, который по-прежнему оставляет много возможностей для реализации поставщиками странными способами (он должен быть арифметическим типом, но не определены диапазоны или максимальные значения) - стандарт C11:

7.27.1 Компоненты времени.
[...]
3. Объявленные типы size_t (описаны в 7.19);
    clock_t
и
time_t
которые являются реальными типами, способными представлять времена;
4. Диапазон и точность времени, представляемого в clock_t и time_t, равны от реализации.

size_t описывается в C11 как "это целочисленный тип без знака результата оператора sizeof";

В свете этого ваш комментарий ( "Я считаю разумным, чтобы он вписывался в long" ) был понятным, но он был неправильным или, по крайней мере, неточным. POSIX, например, требует, чтобы time_t был целым или реальным плавающим типом. A long соответствует этому описанию, но так же будет long double, который не вписывается в long. Более точное предположение заключается в том, что минимальный размер time_t составляет 32 бита int (до 2038 по меньшей мере), но time_t предпочтительно представляет собой 64-битный тип.

В любом случае, в те дни, если значение не могло быть возвращено, единственной альтернативой было передать память функции (что разумно делать).
Вот почему мы имеем такие функции, как

time_t time(time_t *t);

На самом деле не имеет смысла устанавливать одно и то же значение дважды: один раз, возвращая его, и один раз используя косвенное действие, но аргумент есть, потому что изначально функция была определена как

time(time_t *t)

Обратите внимание на отсутствие возвращаемого типа, если time был добавлен сегодня, он либо будет определен как void time( time_t * ), либо если комитет не выпил, а осознал абсурдность передачи указателя здесь, они определяли бы его как time_t time ( void );

Глядя на стандарт C11 относительно функции времени, кажется, что акцент поведения функций на возвращаемом значении. Аргумент указателя упоминается кратко, но это, безусловно, не имеет никакого значения:

7.27.2.4 Временная функция

1. Сводка

#include <time.h>
time_t time(time_t *timer);

2. Описание

Функция времени определяет текущее время календаря. Кодирование значения не определено.

3. Возвращает

Функция времени возвращает наилучшее приближение реализаций к текущему время календаря. Значение (time_t) (- 1) возвращается, если календарное время не доступный. Если таймер не является нулевым указателем, возвращаемое значение также присваивается объекту it указывает на.

Главное, что мы можем извлечь из этого, состоит в том, что, насколько стандарт идет, указатель является лишь второстепенным способом получения возвращаемого значения функции. Учитывая, что возвращаемое значение указывает, что что-то пошло не так ((time_t)(-1)), я бы сказал, что мы должны рассматривать эту функцию так, как будто она должна быть time_t time( void ).

Но поскольку старая реализация по-прежнему ногами, и мы все привыкли к ней, это одна из тех вещей, которые должны были быть отмечены для устаревания, но поскольку она никогда не была такой, она, вероятно, будет частью язык C навсегда...

Единственная причина, почему функции используют time_t как это (const) либо исторически, либо поддерживать согласованный API в API time.h. AFAIK, который

TL; DR

Большинство time.h используют указатели использования для типа time_t для целей истории, совместимости и согласованности.


Я знал, что я прочитал этот материал о первых днях функции time раньше, вот связанный ответ SO

Ответ 2

Вероятно, причина в том, что в старые времена параметр мог быть не больше целого, поэтому вы не могли пройти долго и должны были сделать это как указатель. Определение функции никогда не менялось.