JPCERT コーディネーションセンター

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 修飾した変数を変更するコードが存在しないことが確認できたなら、プログラムのデザインにもっともしっくりくるように、列挙定数やマクロに変更することを考えてもよいだろう。

違反コード

以下のコードでは、pifloat として宣言されている。pi は数学的には定数であるが、不意な変更からは保護されていない。

float pi = 3.14159f;
float degrees;
float radians;
/* ... */
radians = degrees * pi / 180;
適合コード

以下の適合コードでは、piconst 修飾オブジェクトとして宣言している。

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
93 D
200 S

実装済み

PRQA QA-C 8.1

3204
3227
3232

部分的に実装済み
関連するガイドライン
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)

Top へ

Topへ
最新情報(RSSメーリングリストTwitter