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

EXP45-C. 選択文に対して代入を行わない

次の場合は代入演算子を使用しないこと。このような代入演算子は、プログラマが間違いを犯していることを示唆しており、予期せぬ動作を引き起こす可能性がある。

違反コード

次のコード例では、代入式が if 文の最も外側の式になっている。

if (a = b) {
  /* ... */
}

このコードの意図は、ab を代入して結果の値が 0 と等しいかを判定することである可能性もあるが、プログラマの間違いで等価演算子 == の代わりに代入演算子 =が使用されている場合が非常に多い。そのため、多くのコンパイラがこの条件文を警告する。このコーディングエラーは、「MSC00-C. 高い警告レベルで警告を出さずにコンパイルする」に従うことで検知できる。

適合コード

コードの意図が ab を代入することでないならば、次のように修正すると、ab が等しい場合に条件ブロックが実行される。

if (a == b) {
  /* ... */
}

実際に代入を意図している場合の適合コードは次のようになる。

if ((a = b) != 0) {
  /* ... */
}

条件式に代入式が混ざっているため、プログラマの意図にもよるが、一般にこのコードは好ましいとはいえない。とはいえ、プログラマの意図が代入であることは明らかである。

違反コード

次のコード例では、式 x = ywhile 文の制御式として使用している。

do { /* ... */ } while ( foo(), x = y ) ;
適合コード

コードの意図が xy を代入することでないならば、次のように修正すると、xy が等しい場合に条件ブロックが実行される。

do { /* ... */ } while ( foo(), x == y ) ; 

実際に代入を意図している場合の適合コードは次のようになる。

do { /* ... */ } while ( foo(), (x = y) != 0) ;
違反コード

次のコード例では、式 p = qwhile 文の制御式として使用している。

do { /* ... */ } while ( x = y, p = q ) ;
適合コード

x = ywhile 文の制御式として使用されていないため、これは適合コードである。

do { /* ... */ } while ( x = y, p == q ) ; 
例外

EXP45-EX1: 代入の結果自体が比較式または関係式のパラメータである場合、代入を使用することができる。

次のコード例では、式 x = y 自体が比較式のパラメータである。

if ( ( x = y )  != 0  ) { /* ... */ } 

EXP45-EX2: 式が 1 つの一次式で構成されている場合、代入を使用することができる。

次のコード例では、式 x = y は 1 つの一次式である。

if ( ( x = y ) ) { /* ... */ } 

EXP45-EX3: 上記のコンテキストでは、関数の引数または配列のインデックスの場合に代入を使用することができる。

次のコード例では、式 x = y は関数の引数で使用される。

if ( foo( x = y ) ) { /* ... */ }

&& が比較演算子でも関係演算子でもなく、式全体が一次式でないため、これは違反コードである。

if ( ( v = w ) && flag ) { /* ... */ }

w への v の代入が意図されていない場合、この条件ブロックは vw に等しい場合に実行される。

if ( ( v == w ) && flag ) { /* ... */ };

代入を意図している場合には、適合コードは次のようになる。

if ( ( (v = w) != 0 ) && flag ) { /* ... */ };
リスク評価

必要な文字を書き忘れると、意図しないプログラムフローを引き起こすことがある。

ルール

深刻度

可能性

修正コスト

優先度

レベル

EXP45-C

P6

L2

自動検出

ツール

バージョン

チェッカー

説明

Compass/ROSE

 

 

if 文または while 文の最上位式として代入式を識別することによって、このレコメンデーションの違反を検出できる。

ECLAIR

1.1

exprctxt

実装済み

GCC

V. 4.3.5

 

-Wall フラグを使用すると、このレコメンデーションの違反を検出できる。

Klocwork

V. 9.1

ASSIGCOND.GEN
ASSIGCOND.CALL

 

LDRA tool suite

V. 8.5.4

9 S

 

PRQA QA-C 8.1 3314 部分的に実装済み
関連するガイドライン
CERT C++ Secure Coding Standard EXP19-CPP. Do not perform assignments in conditional expressions
ISO/IEC TR 24772:2013 Likely Incorrect Expression [KOA]
ISO/IEC TS 17961 (ドラフト) No assignment in conditional expressions [boolasgn]
MITRE CWE CWE-480, Use of incorrect operator
参考資料
[Hatton 1995] Section 2.7.2, "Errors of Omission and Addition"
翻訳元

これは以下のページを翻訳したものです。

EXP45-C. Do not perform assignments in selection statements (revision 42)

Top へ

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