メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

= 演算子の無効な使用

条件付きステートメント内の代入

説明

この欠陥は、ifwhile などの条件付きステートメントの述部内で代入が行われた場合に発生します。

C および C++ では、単一の等号は比較ではなく代入を表します。条件付きステートメントで単一の等号を使用している場合は、誤入力やミスである可能性があります。

代入対象のオブジェクトが代入演算子と同じステートメント (初期化子を使用した if ステートメントなど) で宣言されている場合、Polyspace®"= (代入) 演算子の無効な使用" を報告しません。たとえば、次のコード スニペット内の変数 tol は、if ステートメント内で宣言されて関数 tolerance の戻り値が代入されますが、Polyspace は = 演算子の使用を違反として報告しません。

#include <iostream>
#include <stdexcept>
#include <string>

extern float tolerance(float actual, float expected);
enum STATUS
{
  FAIL,
  PASS
};

STATUS func(float val, float size)
{
  if (auto tol = tolerance(val, size) < 0.01f) /* No defect. Equivalent to
  
                                                auto tol = tolerance(val, size);
                                                if( tol < 0.01f) */
  {
    return PASS;
  }
  else
  {
    std::string errorMsg = "Tolerance exceeded by " + std::to_string(tol - 0.01f);
    throw std::runtime_error(errorMsg);
  }
}

リスク

  • 条件付きステートメントによる間違った値のテスト - 単一等号の演算は右辺のオペランドの値を左辺のオペランドに代入します。この代入は条件付きの述部内で行われるため、プログラムでは左辺のオペランドの新しい値が非ゼロかつ非 NULL であることがチェックされます。

  • 保守およびコードの可読性の問題 - 代入を意図した場合でも、コードを読む際、または更新する際に、代入ではなく、誤って等値比較と解釈する可能性があります。

修正方法

すべて展開する

#include <stdio.h>

void bad_equals_ex(int alpha, int beta)
{
    if(alpha = beta)
    {
        printf("Equal\n");
    }
}

if ステートメントの述部内で代入演算子が使用されているため、この等号に欠陥としてのフラグが付けられます。述部は、値 betaalpha に代入し、次に alpha が true か false かを暗黙的にテストします。

修正 — 式を比較に変更

1 つの修正方法として、等号を追加することができます。この修正により、代入が比較に変わります。if 条件は alphabeta が等しいかどうかを比較します。

#include <stdio.h>

void equality_test(int alpha, int beta)
{
    if(alpha == beta)
    {
        printf("Equal\n");
    }
}
修正 - if 条件内での代入と比較

述部内で代入を行わなければならない場合、考えられる 1 つの修正方法として、明示的な比較を追加します。この修正により、beta の値が alpha に代入され、次に alpha が非ゼロであるかどうかが明示的にチェックされます。コードが明確になります。

#include <stdio.h>

int assignment_not_zero(int alpha, int beta)
{
    if((alpha = beta) != 0)
    {
        return alpha;
    }
    else
    {
        return 0;
    }
}
修正 — if ステートメント外部に代入を移動

制御ステートメント外部で代入を行うことができる場合、考えられる 1 つの修正方法として、代入と比較を分離します。この修正により、if の前に beta の値が alpha に代入されます。if 条件内では alpha のみを指定し、alpha が非ゼロかつ非 NULL であることをテストします。

#include <stdio.h>

void assign_and_print(int alpha, int beta)
{
    alpha = beta;
    if(alpha)
    {
        printf("%d", alpha);
    }
}

結果情報

グループ: プログラミング
言語: C | C++
既定値: 手書きコードはオン、生成コードはオフ
コマンド ライン構文: BAD_EQUAL_USE
影響度:Medium

バージョン履歴

R2013b で導入