Максимальные значения для time_t (struct timespec) - PullRequest
13 голосов
/ 11 апреля 2011

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

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

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

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

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

Ответы [ 7 ]

27 голосов
/ 28 мая 2014

Поскольку люди здесь отвечают, как установить максимальное значение time_t, и делают дальнейшие предположения относительно его типа, я решил добавить c++ способ сделать это:

#include <limits>
...
time_t maxTime = std::numeric_limits<time_t>::max();
3 голосов
/ 11 апреля 2011

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

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

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

3 голосов
/ 11 апреля 2011

time_t - это просто long int.
Он определен в (в моей системе Ubuntu linux) /usr/include/time.h, однако определение тянется до / usr / include / bits / types.h, где определено __SLONGWORD_TYPE (это то, для чего определено __TIME_T_TYPE).

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

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

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

2 голосов
/ 30 сентября 2016

К сожалению, стандарт 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 является плавающим типом, но если это не так, я подозреваю, что такие платформы будут иметь серьезные проблемы с плавающей точкой расчеты.

2 голосов
/ 25 марта 2015

Взято из ИСО / МЭК 9899: TC3 §7.23

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

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

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

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

1 голос
/ 11 апреля 2011

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

0 голосов
/ 31 октября 2018

Для LINUX ctime может принять любое time_t, которое будет поддерживать результирующий год ниже или равным пределу INT_MAX, то есть для 64-битной системы:

time_t maxtime = 67767976233521999;
printf("%s\n", ctime(&maxtime));

Будет выдавать следующий вывод: Tue Dec 31 23:59:59 2147483647

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...