私はstruct timespec
構造体を使用していますが、これは次のとおりです。
struct timespec {
time_t tv_sec; /* Seconds */
long tv_nsec; /* Nanoseconds */
};
つまり、ユーザーはこれらの個々のメンバーのそれぞれの値を入力するので、最大でチェックを入れたいと思います。ユーザーが入力できる値。
最大を取ることはできますか? time_t
の値をint最大値として?つまり、INT_MAX
の場合はtv_sec
、LONG_MAX
の場合はtv_nsec
(limits.hで定義)?両方の最小許容値は何ですか?ゼロですか?負の値は受け入れられないと思いますか?追加するだけで、これらの値はタイマーで使用されます。
追伸:time_t
のtypedefはどこにありますか?時間内にそれを見つけることができませんでした。h。
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非常に面倒です。お役に立てれば。
ここの人々は最大のtime_t
値を設定する方法に答えており、そのタイプについてさらに推測するので、私はそれを行うためにc++
の方法を追加すると思いました。
#include <limits>
...
time_t maxTime = std::numeric_limits<time_t>::max();
time_t
に何が入るかについてはあまり気にしませんが、何が合理的かについては気にします。私が見たどのシステムでも、time_t
は63年から10年までの期間をエンコードできます11 年(私が知っているほとんどすべてのシステムは、これらの天才が1999年にY2Kの世界を終わらせるものを思いついたので、64ビット数を使用しています。2038年が過ぎたときに誰がはるかに大きな「イベント」に気付くかはまだわかりません。 )。
合理的に期待するプログラムの実行期間が50年以内である場合は、50 * 365 * 86400を超える値を拒否するか、単に値を飽和させます。私が今書いているプログラムが50年以内に使用されるとは思っていません(それを確認するために生きることはありませんが)。
一方、システムがdoes 32ビットtime_t
を使用している場合は、いずれにしてもシステム時間が50年でオーバーフローするため、問題ありません。 、したがって、エポックをシフトせずにとにかく意味のある時間を構築することはできません。
「どのくらい一時停止しますか?」と尋ねると、ユーザーが「250年」と言った場合、「ええ、50年でもかまいません」と言ったとしても、プログラムの動作が本当に間違っているわけではないと思います。なぜなら、ちょっと、違いは実際には観察できないからです。
残念ながら、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節)。定義上、実数型は整数型または実数浮動小数点型(float
、double
またはlong double
、およびおそらく6.11.1項で述べたように、標準の将来のバージョンで追加される他のもの。したがって、time_t
が整数型でない場合、それは必然的に実際の浮動型です。結果として、time_t
が整数型であるかどうかをテスト(time_t) 1 / 2 == 0
で検出できます。
注:C標準では、T
が浮動小数点型の場合、(T) 1 / 2
が0と異なることを厳密に要求していませんが、そうでない場合、そのようなプラットフォームでは浮動小数点に深刻な問題があると思われます。 -ポイント計算。
ISO/IEC 9899:TC §7.23から取得
宣言されているタイプは
size_t
(7.17で説明)です。clock_t
およびtime_t
は、時間を表すことができる算術型です。struct tm
は、内訳時間と呼ばれるカレンダー時間のコンポーネントを保持します。
clock_t
とtime_t
で表現できる時間の範囲と精度は実装によって定義されます
したがって、C標準に基づく最大値を想定することはできません。
ポータブルコードを作成する必要がある場合は、おそらくオートトールを使用します。 Autoconf は、アーキテクチャ固有のデータ制限を処理するのに役立つ AC_CHECK_SIZEOF マクロを提供します。
Wikipediaによると、time_t
は整数または浮動小数点数ですが、通常は32ビットまたは64ビットの符号付き整数です。あなたが想定できる最大の安全な値はINT_MAX
だと思います。 time_t
の場合、少なくとも負の数は合法であり、1970年1月1日より前を参照してください。
LINUXの場合、ctime
は、結果の年をINT_MAX制限以下に保つ任意のtime_t
を受け入れることができます。つまり、64ビットシステムの場合です。
time_t maxtime = 67767976233521999;
printf("%s\n", ctime(&maxtime));
次の出力が生成されます:Tue Dec 31 23:59:59 2147483647