ctime returning null

早过忘川 提交于 2020-06-17 03:47:28

问题


If the user type time_t is defined as __darwin_time_t, which itself is defined as long in MacOS X, why does the following code outputs 8 Time is (null)? Maybe it's something silly, but I can't really understand it.

#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;
}

回答1:


Time 0x7FFFFFFFFFFFFFFF appears to be around the year 292,471,210,647 AD, which undoubtedly causes ctime to exceed the 26 characters it is guaranteed by C99, so it returns NULL rather than overflowing its buffer. In general, try to avoid any dates that occur after the Morlocks go to war with the Eloi.




回答2:


While working through the book "Expert C Programming", I ran across the same problem in Lion 10.7.3 -- with t=0xf0c00000000000, ctime(&t) yields Wed Mar 1 21:07:12 214739252 and with t=0xf0d00000000000, ctime(&t) returns the null pointer (0x0). So it doesn't appear to be a wrap around for t, but some test inside ctime(&t) that returns the null pointer if t is too large.




回答3:


From glibc's implementation we read:

We limit the size of the year which can be printed. Using the %d format specifier used the addition of 1900 would overflow the number and a negative vaue is printed. For some architectures we could in theory use %ld or an evern larger integer format but this would mean the output needs more space. This would not be a problem if the 'asctime_r' interface would be defined sanely and a buffer size would be passed.

Run the program below to find the exact limit on your machine.

#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;
}

For me that comes out to Tue Dec 31 23:59:59 2147483647 which happens to be the second before the year overflows four signed bytes.



来源:https://stackoverflow.com/questions/6035000/ctime-returning-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!