DCL00-C. 不変(immutable)オブジェクトは const 修飾する
不変(immutable)オブジェクトは const
修飾すべきである。const
修飾によってオブジェクトが変更できないことを強制することは、アプリケーションの正しさとセキュリティを保証するのに役立つ。たとえば ISO/IEC TR 24772 は、変数が定数であることをラベル付けして、関数の引数が予期せず変更されることを避けるよう推奨している。[ISO/IEC PDTR 24772]「STR05-C. 文字列リテラルの参照には const へのポインタを使用する」はこのレコメンデーションの特殊なケースについて記述している。
const
修飾を追加しはじめると、結局プログラム全体にわたって const
修飾を追加するはめになるかもしれない。つまりひとつ const
修飾を追加したら、もっと必要になってしまうというように。この現象は const
poisoning と呼ばれることがあり、「EXP05-C. const 修飾をキャストではずさない」の違反を引き起こしかねないことが多い。const
修飾はすぐれた考え方ではあるが、既存のコードを修正するコストが、得られる価値を上回るかもしれない。
const
修飾オブジェクトのかわりにマクロや列挙定数を使うこともできる。const
修飾オブジェクト、列挙定数、オブジェクト形式マクロのそれぞれを使用した場合のメリットについては、「DCL06-C. リテラル値を表現するには意味のあるシンボル定数を使う」に詳しく説明している。しかし、既存の変数を const
修飾することは、これらの変数を列挙定数やマクロに置き換えることに先立ち、まず最初にとるべきステップである。なぜなら、コンパイラは const
修飾された変数を変更しようとするあらゆるコードに対して警告してくれるからである。const
修飾した変数を変更するコードが存在しないことが確認できたなら、プログラムのデザインにもっともしっくりくるように、列挙定数やマクロに変更することを考えてもよいだろう。
違反コード
以下のコードでは、pi
は float
として宣言されている。pi
は数学的には定数であるが、不意な変更からは保護されていない。
float pi = 3.14159f; float degrees; float radians; /* ... */ radians = degrees * pi / 180;
適合コード
以下の適合コードでは、pi
を const
修飾オブジェクトとして宣言している。
const float pi = 3.14159f; float degrees; float radians; /* ... */ radians = degrees * pi / 180;
リスク評価
不変(immutable)オブジェクトを const
修飾し忘れると、実行時に定数が変更される恐れがある。
レコメンデーション |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
DCL00-C |
低 |
低 |
高 |
P1 |
L3 |
自動検出(最新の情報はこちら)
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
Compass/ROSE |
|
|
|
ECLAIR |
1.1 |
cnstpnte |
部分的に実装済み |
LDRA tool suite |
V. 8.5.4 |
78 D |
実装済み |
PRQA QA-C | 8.1 |
3204 |
部分的に実装済み |
関連するガイドライン
CERT C++ Secure Coding Standard | DCL00-CPP. Const-qualify immutable objects |
参考資料
[Dewhurst 2002] | Gotcha #25, "#define Literals" |
[Saks 2000] |
翻訳元
これは以下のページを翻訳したものです。
DCL00-C. Const-qualify immutable objects (revision 120)