DCL01-C. サブスコープで変数名を再利用しない
あるスコープが他方のスコープに包含されるような二つのスコープで同一の変数名を使用しないこと。たとえば、次のような例が考えられる。
- いかなる変数も、その変数がグローバル変数のサブスコープにあるならば、グローバル変数の名前を共有してはならない。
- あるブロックは、そのブロックを包含するいかなるブロックで宣言されている変数とも、同じ名前の変数を定義してはならない。
変数名を再利用すると、どの変数が変更されているのだろうという混乱をプログラマに与える。また、変数名が再利用されているというのは、変数名が一般的過ぎるということでもある。
違反コード
以下のコード例では、ファイル有効範囲で msg
識別子を定義し、同じ識別子を使って report_error()
関数にローカルな文字配列を宣言している。プログラマは意図せず、report_error()
関数にローカルに宣言された msg
配列へ文字列をコピーする可能性がある。プログラマの意図によって異なるが、このことで、グローバル変数の msg
を初期化し損ねるか、または、ローカルバッファに対する境界としてグローバル値 msgsize
を使用することでローカル msg
バッファのオーバーフローを誘発する可能性がある。
static char msg[100]; static const size_t msgsize = sizeof( msg); void report_error(const char *str) { char msg[80]; snprintf(msg, msgsize, "Error: %s\n", str); /* ... */ } int main() { /* ... */ report_error("some error"); }
適合コード
以下の適合コードでは、より説明的な違う名前を使っている。
static char message[100]; static const size_t message_size = sizeof( message); void report_error(const char *str) { char msg[80]; snprintf(msg, sizeof( msg), "Error: %s\n", str); /* ... */ } int main() { /* ... */ report_error("some error"); }
ブロックが小さい場合、変数宣言がすぐに目に見えるため、変数名を再利用する危険性は緩和される。しかし、上記の例であっても、変数名を再利用することは望ましくない。通常、識別子の宣言区域が広がれば、それに伴って識別子の名前はより説明的になり言葉数は増える。
グローバルにもローカルにも異なる変数名を使用することで、コンパイラは、ディベロッパーが変数名に関してより厳密かつ説明的であることを強制する。
例外
DCL01-EX1: 関数宣言内の関数の引数は、関数定義の際に、その関数を包含するどのスコープ内のどの変数とも衝突しない名前を割り当てても、その関数を包含するいずれかのスコープ内の変数と衝突する可能性がある。
extern int name; void f(char *name); // 宣言: ここには問題はない // ... void f(char *arg) { // 定義: 問題はない、arg は名前を隠さない // use arg }
リスク評価
サブスコープで変数名を再利用すると、間違った変数を意図せず参照することにつながりうる。
レコメンデーション |
深刻度 |
可能性 |
修正コスト |
優先度 |
レベル |
---|---|---|---|---|---|
DCL01-C |
低 |
低 |
中 |
P2 |
L3 |
自動検出(最新の情報はこちら)
ツール |
バージョン |
チェッカー |
説明 |
---|---|---|---|
Compass/ROSE |
|
|
|
ECLAIR |
1.1 |
declhidn |
実装済み |
V. 9.1 |
IF_MULTI_DECL |
|
|
LDRA tool suite |
V. 8.5.4 |
131 S |
実装済み |
PRQA QA-C | 8.1 |
2547 |
実装済み |
Splint |
V. 3.1.1 |
|
|
関連するガイドライン
CERT C++ Secure Coding Standard | DCL01-CPP. Do not reuse variable names in subscopes |
MISRA-C |
Rule 5.2 |
翻訳元
これは以下のページを翻訳したものです。
DCL01-C. Do not reuse variable names in subscopes (revision 114)