ctime возвращает ноль - PullRequest
       18

ctime возвращает ноль

0 голосов
/ 17 мая 2011

Если пользовательский тип time_t определен как __darwin_time_t, который в MacOS X определен как long, почему следующий код выводит 8 Time is (null)? Может быть, это что-то глупое, но я не могу этого понять.

#include <stdio.h>
#include <time.h>

int main(void)
{
    time_t time = 0x7FFFFFFFFFFFFFFF;

    printf("%lu\n"
           "Time is %s\n", sizeof(time_t), ctime(&time));

    return 0;
}

Ответы [ 3 ]

7 голосов
/ 17 мая 2011

Время 0x7FFFFFFFFFFFFFFF примерно в 292 471 210 647 году нашей эры, что, несомненно, приводит к тому, что ctime превышает 26 символов, гарантируемых C99, поэтому он возвращает NULL, а не переполняет свой буфер.В общем, старайтесь избегать любых дат, которые происходят после того, как морлоки вступили в войну с Элои.

2 голосов
/ 27 февраля 2012

Работая с книгой «Программирование на Expert C», я столкнулся с той же проблемой в Lion 10.7.3 - с t=0xf0c00000000000, ctime(&t) выдает Wed Mar 1 21:07:12 214739252 и с t=0xf0d00000000000, ctime(&t) возвращает нулевой указатель (0x0).Таким образом, это не выглядит как обертка для t, но некоторый тест внутри ctime(&t), который возвращает нулевой указатель, если t слишком велико.

1 голос
/ 03 декабря 2014

Из реализации glibc мы читаем:

Мы ограничиваем размер года, который может быть напечатан.При использовании спецификатора формата% d добавление 1900 переполняет число и выводится отрицательное значение.В некоторых архитектурах мы могли бы теоретически использовать% ld или более широкий целочисленный формат, но это означало бы, что для вывода требуется больше места.Это не будет проблемой, если интерфейс 'asctime_r' будет определен разумно и размер буфера будет передан.

Запустите программу ниже, чтобы найти точное ограничение на вашем компьютере.

#include <limits.h>
#include <stdio.h>
#include <time.h>

/**
 * Find the largest time_t for which ctime returns a non-NULL value
 * using a bsearch between 0 and LONG_MAX.
 **/
static time_t ctime_max() {
    time_t start = 0, end = LONG_MAX, mid;
    while (start < end) {
        mid = start + (end - start) / 2;
        if (ctime(&mid)) {
            /* this mid is ctime-able; try higher */
            start = mid + 1;
        } else {
            /* this mid is not ctime-able; try lower */
            end = mid;
        }
    }
    /* mid is now the lowest number that's too high; subtract one */
    return mid - 1;
}

int main() {
    time_t t = ctime_max();
    printf("%s", ctime(&t));
    return 0;
}

Для меня это выходит на Tue Dec 31 23:59:59 2147483647, который является вторым до того, как год переполняет четыре подписанных байта.

...