2011-05-17 68 views
0

如果用戶類型time_t被定義爲__darwin_time_t,它本身在MacOS X中定義爲long,爲什麼下面的代碼輸出8 Time is (null)?也許這是愚蠢的,但我不能真正理解它。ctime返回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; 
} 
+0

我的意思是'__darwin_time_t',而不是'__darwin_time',對不起。 – sidyll 2011-05-17 18:01:41

回答

7

時間0x7FFFFFFFFFFFFFFF似乎是圍繞今年292471210647 AD,這無疑會導致ctime超過26個字符它是由C99保證,所以它返回NULL,而不是它的溢出緩衝區。一般來說,儘量避免在Morlock與Eloi交戰之後發生的任何日期。

+1

嗯,這個想法是要找出'time_t'什麼時候會環繞。 Unix時代的0x7FFFFFFF將在2038年發生,所以我想我們需要一個新的標準,然後星系間的戰爭開始發生在銀河系中。 – sidyll 2011-05-17 18:21:47

+1

改爲嘗試strftime。或者只是檢查localtime或gmtime的tm_year。 – Random832 2011-05-17 19:11:43

2

雖然經書「C專家編程」的工作,我碰到了同樣的問題在獅跑10.7.3 - 與t=0xf0c00000000000ctime(&t)產量Wed Mar 1 21:07:12 214739252t=0xf0d00000000000, ctime(&t)返回空指針(爲0x0)。 所以它看起來並不是對t的包裝,但是在ctime(&t)裏面的一些測試在t太大時返回空指針。

+2

只是做了同樣的事情。滑稽。 – Suboptimus 2013-07-19 21:01:16

1

glibc's implementation,我們讀到:

我們限制可打印的大小年。使用%d 格式說明符時,使用1900的補充將溢出 號碼並打印負值。對於某些體系結構,我們 理論上可以使用%ld或evern較大的整數格式,但這可能意味着輸出需要更多空間。如果'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這恰好是第二年溢出4個符號字節之前。