EXP07-C. 式中で、定数の値を仮定して定数を使うメリットを損なわない
ある識別子に定数値が与えられている場合、その識別子が使われているコードのメンテナンス性を、式中でその値を仮定することで損なわないこと。定数に名前(識別子)を割り当てるだけではコードのメンテナンス性を保証するまでには至らない。常にその識別子を使うように気をつけ、その識別子が表す値が変わることもあるということに注意したコードにしなくてはならない。このレコメンデーションは、「DCL06-C. プログラムロジックでリテラル値を表現するには意味のあるシンボル定数を使う」と関係がある。
違反コード
ヘッダ stdio.h
は BUFSIZ
マクロを定義しており、これは setbuf()
関数が使用するバッファサイズを表す整数定数式に展開される。このコード例は、次に示す式の中で BUFSIZ
の値を決めてかかっており、BUFSIZ
を定数として定義するという目的を台無しにしている。
#include <stdio.h> /* ... */ nblocks = 1 + ((nbytes - 1) >> 9); /* BUFSIZ = 512 = 2^9 */
このコードに隠されたプログラマの勝手な思い込みは、「みんな BUFSIZ
が 512 だということを知っている」だから、9 ビット (正の数を) 右シフトすることは 512 で割ることと同じだ、というものである。しかし、もしあるシステムで BUFSIZ
が 1024 に変更されたら、コードの修正はやっかいで間違いを起こしやすい。
適合コード
この適合コードでは式中の定数値に識別子を割り当てている。
#include <stdio.h> /* ... */ nblocks = 1 + (nbytes - 1) / BUFSIZ;
最近のCコンパイラであれば、このコードを適切に最適化してくれる。
リスク評価
式の値を勝手に思い込んでコーディングすると、コードのメンテナンス性が損なわれ、定数の値が変更されるような状況では予期せぬ動作につながる恐れがある。
レコメンデーション |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
EXP07-C |
低 |
低 |
中 |
P2 |
L3 |
自動検出(最新の情報はこちら)
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
LDRA tool suite | V. 8.5.4 | 201 S |
実装済み |
PRQA QA-C | 8.1 | 3120 |
部分的に実装済み |
関連するガイドライン
CERT C++ Secure Coding Standard | EXP07-CPP. Do not diminish the benefits of constants by assuming their values in expressions |
参考資料
[Plum 1985] | Rule 1-5 |
翻訳元
これは以下のページを翻訳したものです。
EXP07-C. Do not diminish the benefits of constants by assuming their values in expressions (revision 44)