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

安全・安心なIT社会のための、国内・国際連携を支援する

お問い合わせ サイトマップ English

Home > ラーニング > セキュアコーディング > C セキュアコーディングスタンダード > 02. 宣言と初期化 (DCL)

  1. HTTPS

02. 宣言と初期化 (DCL)

最終更新: 2010-07-26

DCL00-C. イミュータブルなオブジェクトは const 修飾する

イミュータブルなオブジェクトは const 修飾すべきである。const修飾によってオブジェクトが変更できないことを強制することは、アプリケーションの正しさとセキュリティを保証するのに役立つ。たとえば ISO/IEC PDTR 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;
違反コード

以下のコード例ではマクロを使って最大値を定義しているが、マクロには型情報がない。[Dewhurst 02]

#define MAX (1<<16)
// ...
void f(int);
void f(long);
// ...
f(MAX);  // どっちの f かな?

1 << 16 はプラットフォームによっては int にも long にもなりうる。そのため、このコードはプラットフォーム依存になっている。

適合コード

const を使うことで値に型情報がつけられ、混乱がおきる可能性を排除している。

int const max = 1<<16;
// ...
void f(int);
void f(long);
// ...
f(max);
例外

DCL00-EX1: 値を定義しないマクロをインクルードガードのために定義することは許される。つまり、以下に示す例のように、マクロはヘッダファイルを複数インクルードするのを制御する。

#ifndef SOME_HEADER_H
#define SOME_HEADER_H
...  // content of header file
#endif

インクルードガードの詳細は「PRE06-C. ヘッダファイルはインクルードガードで囲む」を参照のこと。

リスク評価

イミュータブルなオブジェクトをconst修飾し忘れると、実行時に定数が変更される恐れがある。

レコメンデーション 深刻度 可能性 修正コスト 優先度 レベル
DCL00-C P1 L3
自動検出

Compass/ROSE はこのレコメンデーションの違反のほとんどを検出することができる。

参考情報
  • [Dewhurst 02] Gotcha #25, "#define Literals"
  • [ISO/IEC 9899:1999] Section 6.7.3, "Type qualifiers"
  • [Saks 00]
翻訳元

DCL00-C. Const-qualify immutable objects

Top へ