メインコンテンツ

言語スコープがしきい値を超えている

関数の言語スコープが、定義済みしきい値を超えている

R2021a 以降

説明

言語スコープは、関数の保守または更新にかかるコストを表します。たとえば、関数で同じオペランドが何度も出現する場合、オペランド名を変更するにはコストがかかります。このような関数の言語スコープは高くなります。この欠陥は、関数の言語スコープが定義済みしきい値を超えている場合に報告されます。Polyspace が言語スコープを計算する方法について詳しくは、言語スコープを参照してください。

メモ

Polyspace® で計算される言語スコープは、浮動小数点数です。このチェッカーでは、浮動小数点の言語スコープが小数第 2 位に丸められてから 100 で乗算されることによって、整数に変換されます。

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

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

リスク

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

  • オペランドの変更で、関数に多数の変更が必要である。

  • 関数が一度に複数のタスクを実行している。

  • 関数が他の関数との高い相互依存性を持つ。

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

修正方法

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

  • 各関数が単一の特定のタスクを実行するようにする。

  • 関数が他の関数に与える二次的影響を最小限にする。

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

すべて展開する

 long long power(double x, int n){
	 long long BN = 1;
	 for(int i = 0; i<n;++i){
		 BN*=x;
	 }
	 return BN;
 }
 
 double AppxIndex(double m, double f){//Noncompliant
	 double U = (power(m,2) - 1)/(power(m,2)+2);
	 double V = (power(m,4) + 27*power(m,2)+38)/(2*power(m,2)+3);
	 return (1+2*f*power(U,2)*(1+power(m,2)*U*V + power(m,3)/
                power(m,3)*(U-V)))/( (1-2*f*power(U,2)*(1+power(m,2)*U*V +
                power(m,3)/power(m,3)*(U-V))));
 }

この例の関数では、オペランド power が何度も繰り返されています。power を変更する場合、関数を慎重に調べて、予期しない動作につながらないようにする必要があります。関数 AppxIndex の言語スコープは 700 であり、既定の言語スコープ 400 を上回っています。Polyspace は、非準拠としてこの関数にフラグを設定します。

修正 — コードをリファクタリング

1 つの修正方法として、コードをリファクタリングして、オペランドが何度も繰り返されないようにします。この例では、関数 AppxIndex がリファクタリングされて、関係のないタスクが独立した関数によって実行されています。これらの関数は準拠しています。

// This code calculates effective index of materials  as decribed in
// the formula in 10.1364...
// power(x,n) returns the nth power of x (x^n)
// n is an integer
// x is a double
// return type is long long
long long power(double x, int n){//Compliant
	long long BN = 1;
	for(int i = 0; i<n;++i){
		BN*=x;
	}
	return BN;
}
// CalculateU(m) calculates the first intermediate variable
// required to calculate  polarization
// m is the relative refractive index
// return type is double;
double CalculateU(double m){//Compliant
	return (power(m,2) - 1)/(power(m,2)+2);
}
// CalculateV(m) calculates the second intermediate variable
// required to calculate  polarization
// m is the relative refractive index
// return type is double;
double CalculateV(double m){//Compliant
	return (power(m,4) + 27*power(m,2)+38)/(2*power(m,2)+3);
}
// CalculateMid(m,f) calculates the large term present in both numerator and denominator
// of the effective index calculation
// m is the relative refractive index
// f is the fillfactor 
// return type is double;
double CalculateMid(double m, double f){//Compliant
	double U = CalculateU(m);
	double V = CalculateU(m); 
	return 2*f*power(U,2)*(1+power(m,2)*U*V + power(m,3)/power(m,3)*(U-V));
}
//AppxIndex(m,f) calculates the approximate effective index
// m is the relative refractive index
// f is the fillfactor
//return type is double
double AppxIndex(double m, double f){//Compliant
	return (1+CalculateMid(m,f))/( (1-CalculateMid(m,f)));
}

チェック情報

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

バージョン履歴

R2021a で導入