web-dev-qa-db-ja.com

time_t(struct timespec)の最大値

私はstruct timespec構造体を使用していますが、これは次のとおりです。

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

つまり、ユーザーはこれらの個々のメンバーのそれぞれの値を入力するので、最大でチェックを入れたいと思います。ユーザーが入力できる値。

最大を取ることはできますか? time_tの値をint最大値として?つまり、INT_MAXの場合はtv_secLONG_MAXの場合はtv_nsec(limits.hで定義)?両方の最小許容値は何ですか?ゼロですか?負の値は受け入れられないと思いますか?追加するだけで、これらの値はタイマーで使用されます。

追伸:time_tのtypedefはどこにありますか?時間内にそれを見つけることができませんでした。h。

14
kingsmasher1

Time_tは単にlongintです。
これは(私のUbuntu Linuxシステムでは)/usr/include/time.hで定義されていますが、定義は/usr/include/bits/types.hまでさかのぼります。ここで、___SLONGWORD_TYPE_ (これは___TIME_T_TYPE_が定義されているものです)が定義されています。

値がたとえば_LONG_MAX_より大きいかどうかを単にチェックする場合の問題は、値がこの値を超えると、自動的に折り返され、負になることです。したがって、この値よりも大きいものがあるかどうかを確認することはできません。マクロは、このタイプが取ることができる最大値として定義されています。

「ユーザー」が「開発者」を意味しない限り、ユーザーにこれらの値を入力させたくはありません。これをテストするための唯一の実際の「安全な」方法は、ユーザーに文字列(もちろん、cスタイル)を入力させてから、2つのチェックを実行することです。
1)ユーザーが許可されているよりも多くの桁を入力したかどうかを確認します(安価なトリックは、数値の桁数を数えるためのint(log10(number)) + 1です)。
2)これが桁数と等しい場合は、桁ごとの比較を開始します。少しのモジュロ演算を使用して、桁ごとに比較できます。

これは、ユーザーが大きすぎる数値を入力したかどうかを確認するための最も安全な方法です。この方法でオーバーフローの問題が発生することはありませんが、is非常に面倒です。お役に立てれば。

2
Ben Stott

ここの人々は最大のtime_t値を設定する方法に答えており、そのタイプについてさらに推測するので、私はそれを行うためにc++の方法を追加すると思いました。

#include <limits>
...
time_t maxTime = std::numeric_limits<time_t>::max();
29
swalog

time_tに何が入るかについてはあまり気にしませんが、何が合理的かについては気にします。私が見たどのシステムでも、time_tは63年から10年までの期間をエンコードできます11 年(私が知っているほとんどすべてのシステムは、これらの天才が1999年にY2Kの世界を終わらせるものを思いついたので、64ビット数を使用しています。2038年が過ぎたときに誰がはるかに大きな「イベント」に気付くかはまだわかりません。 )。

合理的に期待するプログラムの実行期間が50年以内である場合は、50 * 365 * 86400を超える値を拒否するか、単に値を飽和させます。私が今書いているプログラムが50年以内に使用されるとは思っていません(それを確認するために生きることはありませんが)。
一方、システムがdoes 32ビットtime_tを使用している場合は、いずれにしてもシステム時間が50年でオーバーフローするため、問題ありません。 、したがって、エポックをシフトせずにとにかく意味のある時間を構築することはできません。

「どのくらい一時停止しますか?」と尋ねると、ユーザーが「250年」と言った場合、「ええ、50年でもかまいません」と言ったとしても、プログラムの動作が本当に間違っているわけではないと思います。なぜなら、ちょっと、違いは実際には観察できないからです。

3
Damon

残念ながら、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節)。定義上、実数型は整数型または実数浮動小数点型floatdoubleまたはlong double 、およびおそらく6.11.1項で述べたように、標準の将来のバージョンで追加される他のもの。したがって、time_tが整数型でない場合、それは必然的に実際の浮動型です。結果として、time_tが整数型であるかどうかをテスト(time_t) 1 / 2 == 0で検出できます。

注:C標準では、Tが浮動小数点型の場合、(T) 1 / 2が0と異なることを厳密に要求していませんが、そうでない場合、そのようなプラットフォームでは浮動小数点に深刻な問題があると思われます。 -ポイント計算。

2
vinc17

ISO/IEC 9899:TC §7.23から取得

  1. 宣言されているタイプはsize_t(7.17で説明)です。 clock_tおよびtime_tは、時間を表すことができる算術型です。 struct tmは、内訳時間と呼ばれるカレンダー時間のコンポーネントを保持します。

  2. clock_ttime_tで表現できる時間の範囲と精度は実装によって定義されます

したがって、C標準に基づく最大値を想定することはできません。

ポータブルコードを作成する必要がある場合は、おそらくオートトールを使用します。 Autoconf は、アーキテクチャ固有のデータ制限を処理するのに役立つ AC_CHECK_SIZEOF マクロを提供します。

2
Ottavio Campana

Wikipediaによると、time_tは整数または浮動小数点数ですが、通常は32ビットまたは64ビットの符号付き整数です。あなたが想定できる最大の安全な値はINT_MAXだと思います。 time_tの場合、少なくとも負の数は合法であり、1970年1月1日より前を参照してください。

1
sverre

LINUXの場合、ctimeは、結果の年をINT_MAX制限以下に保つ任意のtime_tを受け入れることができます。つまり、64ビットシステムの場合です。

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

次の出力が生成されます:Tue Dec 31 23:59:59 2147483647

0
Borland P