メインコンテンツ

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

呼び出しの入れ子の深さがしきい値を超えている

関数内の制御構造の入れ子の深さが、関数の入れ子の深さに対して定義されているしきい値を超えている

R2021a 以降

説明

この欠陥は、forif-elseswitchwhile などの関数内の制御構造の入れ子の深さが、入れ子の深さに対して定義されているしきい値を超えている場合に報告されます。Polyspace® が入れ子の深さを計算する方法について詳しくは、呼び出しレベルの数を参照してください。

Polyspace は、ユーザーがしきい値を指定しない限り、既定のしきい値として 4 を使用します。しきい値を指定できる選択ファイルを指定するには、オプション [ファイルごとにチェッカーを設定] (-checkers-selection-file) または [チェッカー アクティベーション ファイル] (-checkers-activation-file) を使用します。

polyspace-comments-import を使用して以前の解析からコメントをインポートすると、Polyspace は以前の結果のコード メトリクスの呼び出しレベルの数に関するレビュー情報を、このチェッカーの現在の結果にコピーします。現在の結果に同じコード メトリクスが含まれている場合、レビュー情報はそのコード メトリクスにもコピーされます。

リスク

このチェッカーに違反している場合は、次の可能性があります。

  • 関数が読みづらく、わかりにくい。

  • 関数が一度に実行するタスクが多すぎる。

  • 関数で不測の、または計画外の状況に発展する。

これらの要因により、モジュールの保守とデバッグが困難になります。

修正方法

このチェックを修正するには、コードをリファクタリングするか、チェッカーのしきい値を変更します。コードをリファクタリングする場合は、次のようにします。

  • 関数が単一のタスクを実行するように設計する。

  • 関係のないタスクは他の関数にデリゲートする。

ベスト プラクティスは、開発後のリファクタリング コストを回避するために、開発の早期段階でモジュールの複雑度をチェックすることです。

すべて展開する

int foo(int i, int j, int k) //Noncompliant
{
	int m = 0;
	for(i = 0; i < 10; i++)
	{
		for(j = 0; j < 10; j++)
		{
			for(k = 0; k < 10; k++)
			{
				if(i < 2 && j > 5 && k < 7)
					m += 1;
				else
				{
					if(i > 5 && j < 8 && k > 8) {
						m += -1 ;
					} else
						if(i == j) {
							m += 2;
						} else
							if(j == k) {
								m += 3;
							} else {
								m += 1;
							}
				}
			}
		}
	}
	return m;
}

この例では、呼び出しの入れ子の深さは 7 です。Polyspace は、入れ子の深さを 0 からカウントし、制御構造体ごとに深さをインクリメントします。if-else ブロック内の各 else ブロックが、個別の入れ子の層とみなされます。入れ子を深くすると、事前定義されたしきい値 4 を超えて、読みにくく、更新や保守が困難な関数になります。

修正 — 関数をリファクタリング

1 つの修正方法として、タスクのそれぞれを異なる関数にデリゲートします。たとえば、foo() 内の条件付きアクションを別の関数 getDelta() にデリゲートします。これらの関数の呼び出しの入れ子の深さは、それぞれ 3、4 となっています。これらの関数の呼び出しの入れ子の深さは、しきい値の 4 を超えていません。

int getDelta(int i, int j, int k) { //Compliant
	int delta = 0;
	if(i < 2 && j > 5 && k < 7)
	{
		delta = 1;
	}
	else {
		if(i > 5 && j < 8 && k > 8) {
			delta = -1 ;
		} else
			if(i == j) {
				delta = 2;
			} else
				if(j == k) {
					delta = 3;
				} else {
					delta = 1;
				}
	}

}
int foo(int i, int j, int k) //Compliant
{
	int m = 0;
	for(i = 0; i < 10; i++)
	{
		for(j = 0; j < 10; j++)
		{
			for(k = 0; k < 10; k++)
			{
				m += getDelta(i, j, k);
			}
		}
	}
	return m;
}

チェック情報

グループ: ソフトウェアの複雑度
言語: C | C++
頭字語: SC14
既定のしきい値: 4

バージョン履歴

R2021a で導入