1

ユーザータイプtime_tがとして定義され__darwin_time_t、それ自体がlongMacOS Xのように定義されている場合、次のコードが出力されるのはなぜ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;
}
4

3 に答える 3

9

時間0x7FFFFFFFFFFFFFFFは、西暦292,471,210,647年頃のようです。これは、間違いなくctimeC99で保証されている26文字を超えるため、バッファーをオーバーフローさせるのではなく、NULLを返します。一般的に、モーロックがエロイと戦争をした後に発生する日付は避けてください。

于 2011-05-17T18:06:16.407 に答える
2

「エキスパートCプログラミング」という本を読んでいるときに、Lion 10.7.3で同じ問題に遭遇しました。つまりt=0xf0c00000000000ctime(&t)yieldsWed Mar 1 21:07:12 214739252を使用して t=0xf0d00000000000, ctime(&t)、nullポインター(0x0)を返します。したがって、tのラップアラウンドではないように見えctime(&t)ますが、tが大きすぎる場合にnullポインタを返す内部のテストがあります。

于 2012-02-27T05:05:59.187 に答える
1

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、年が4つの署名されたバイトをオーバーフローする前にたまたま2番目になります。

于 2014-12-03T15:10:55.460 に答える