Максимальные значения для time_t (struct timespec)

Я использую структуру struct timespec, и вот она:

struct timespec {
           time_t tv_sec;                /* Seconds */
           long   tv_nsec;               /* Nanoseconds */
};

Thing is, пользователь будет вводить значения для каждого из этих отдельных членов, и я хочу поставить проверку max. значение, которое пользователь может ввести.

Могу ли я взять max. значение time_t как int max value? я INT_MAX для tv_sec и LONG_MAX (определяется в пределах. h) для tv_nsec? Какими будут минимально приемлемые значения для обоих? Это нуль? Думаю, отрицательные значения не могут быть приняты? Просто чтобы добавить, эти значения будут использоваться в таймере.

P.S: Где typedef для time_t? Не удалось найти его вовремя. H.

Ответ 1

Время_t - просто длинный int.
Он определен в (в моей системе Linux Ubuntu)/usr/include/time.h, однако определение простирается полностью до /usr/include/bits/types.h, где __SLONGWORD_TYPE (что является тем, что __TIME_T_TYPE определяется как).

Проблема с простой проверкой, если значение больше, чем, скажем, LONG_MAX, заключается в том, что как только значение превышает это значение, оно автоматически обернется и станет отрицательным. Таким образом, вы не можете проверить, больше ли это, чем это значение - макрос определяется как наибольшее значение, которое может принимать этот тип.

Вы не хотите, чтобы пользователь вводил эти значения, если только "пользователь" не означает "разработчик". Единственный реальный "безопасный" способ проверить это - позволить пользователю ввести строку (c-style, конечно), а затем выполнить две проверки:
1) Проверьте, не введен ли пользователь больше цифр, чем разрешено (дешевый трюк int(log10(number)) + 1 для подсчета количества цифр в номере).
2) Если это равно количеству цифр, начните сравнивать цифровую цифру. Вы можете сравнивать цифры по цифре, используя немного арифметики по модулю.

Это действительно самый безопасный способ проверить, вводит ли пользователь слишком большой номер. Таким образом, вы не столкнетесь с проблемой переполнения, хотя это ужасно утомительно. Надеюсь, это поможет.

Ответ 2

Так как люди здесь отвечают, как установить максимальное значение time_t и делать дополнительные догадки относительно его типа, я думал, что добавлю способ c++ сделать это:

#include <limits>
...
time_t maxTime = std::numeric_limits<time_t>::max();

Ответ 3

Мне было бы безразлично, что происходит в time_t, но о том, что разумно. В любой системе, которую я видел, time_t может кодировать временные интервалы от 63 лет до 10 11 лет (почти каждая система, которую я знаю, использует 64-битные номера с тех пор, как эти geniusses придумали Y2K во всем мире в 1999 году, еще предстоит выяснить, кто заметит гораздо большее "событие", когда прошло 2038 год).

Если вы разумно ожидаете, что ваша программа будет работать не более 50 лет, отклоните любое значение, превышающее 50 * 365 * 86400, или просто насытите значение. Я не ожидаю, что какие-либо из программ, которые я пишу сейчас, будут использоваться через 50 лет (хотя я не буду это проверять). С другой стороны, если ваша система использует 32-битный time_t, то это не имеет значения, потому что системное время будет переполняться через 50 лет в любом случае, поэтому невозможно построить осмысленное время в любом случае без изменения эпохи.

Если вы спросите, как долго вы хотите сделать паузу? и пользователь говорит "250 лет", я бы счел это не совсем неправильным поведением программы, если бы вы сказали: "Да, правильно, 50 тоже сделают". Потому что, эй, разница действительно не наблюдается.

Ответ 4

Согласно Википедии, time_t может быть целым числом или числом с плавающей запятой, но обычно это 32-битное или 64-разрядное целое число со знаком. Я думаю, что наибольшее безопасное значение, которое вы можете предположить, INT_MAX. Для time_t по крайней мере отрицательные числа являются законными и относятся к ним до 1 января 1970 года.

Ответ 5

К сожалению, стандарт ISO C (в настоящее время C11) не предоставляет никакого способа получить максимальное значение time_t. Поэтому, если вы не используете такие инструменты, как Autoconf, предоставляя информацию, нужно сделать некоторые предположения.

Предполагая, что time_t является целым типом без битов заполнения (что имеет место на большинстве платформ в настоящее время, если не все), можно, вероятно, взять:

(((time_t) 1 << (sizeof(time_t) * CHAR_BIT - 2)) - 1) * 2 + 1

который является максимальным представимым значением для целочисленного типа со знаком (но тот факт, что значение представляется в time_t, не означает, что он поддерживается системой как значение time_t).

Также может потребоваться определить, является ли time_t целым типом. Стандарт ISO C указывает, что time_t является реальным типом (раздел 7.27.1). По определению реальный тип представляет собой либо целочисленный тип, либо реальный плавающий тип (float, double или long double и, возможно, другие, добавленные в будущих версиях стандарта, как указано в разделе 6.11.1). Таким образом, если time_t не является целым типом, он обязательно является реальным плавающим типом. Как следствие, можно определить, является ли time_t целочисленным типом с тестом (time_t) 1 / 2 == 0.

Примечание. Стандарт C строго не требует, чтобы (T) 1 / 2 отличался от 0, если T является плавающим типом, но если это не так, я подозреваю, что такие платформы будут иметь серьезные проблемы с плавающей запятой расчеты.

Ответ 6

Взято из ISO/IEC 9899: TC3 §7.23

  1. Объявленные типы size_t (описаны в 7.17); clock_t и time_t, которые являются арифметическими типами, способными представлять времена; а также struct tm, который содержит компоненты календарного времени, называемые время прерывания.

  2. Диапазон и точность времени, представляемого в clock_t и time_t, определяются реализацией

Поэтому вы не можете делать какие-либо предположения о его максимальном значении на основе стандарта C.

Если вам нужно написать переносимый код, вы, вероятно, будете использовать автоматы. Autoconf предлагает макрос AC_CHECK_SIZEOF, который может помочь вам справиться с специфические для конкретной архитектуры пределы данных.