MSC05-C. time_t 型の値を直接操作しない
time_t は「時刻を表すことができる算術型」と規定されている。しかし、この算術型内での時刻の符号化方法は定められていない。符号化方法が定められていないため、算術型に対して手動で算術演算を実行することは危険であり、値を直接変更すべきでない。
違反コード
以下のコード例は、少なくとも seconds_to_work 秒が経過するまで、 do_work() を複数回実行しようとする。しかし、符号化方法が定義されていないため、start を seconds_to_work に加算しても、必ずしも seconds_to_work 秒追加される保証はない。
int do_work(int seconds_to_work) { time_t start = time(NULL); if (start == (time_t)(-1)) { /* エラー処理 */ } while (time(NULL) < start + seconds_to_work) { /* ... */ } return 0; }
適合コード
以下の解決法は、difftime() を用いて 2 つの time_t 値の差を計算している。difftime() 関数は、第 2 引数から第 1 引数までの秒数と結果を double 型として返す。
int do_work(int seconds_to_work) { time_t start = time(NULL); time_t current = start; if (start == (time_t)(-1)) { /* エラー処理 */ } while (difftime(current, start) < seconds_to_work) { current = time(NULL); if (current == (time_t)(-1)) { /* エラー処理 */ } /* ... */ } return 0; }
time_t の範囲は、seconds_to_work 秒離れた 2 つの時刻を表現できないことがあるため、このループは依然として終了しない可能性がある点に注意。
リスク評価
time_t を正しく使用しないと、プログラムが無限ループに入ったり想定している条件分岐が行われないなど、予期せぬ動作をすることがある。
レコメンデーション | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
---|---|---|---|---|---|
MSC05-C | 低 | 低 | 中 | P2 | L3 |
自動検出
Compass/ROSE はこのレコメンデーションの違反を検出できる。
参考情報
- [Kettlewell 02] Section 4.1, "time_t"
- [ISO/IEC 9899:1999] Section 7.23, "Date and time <time.h>"
翻訳元
これは以下のページを翻訳したものです。