メインコンテンツ

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

循環的複雑度

関数本体における線形独立パス数

説明

このメトリクスは関数内の判定点の数を計算し、合計に 1 を足します。判定点とはプログラムを 2 つのパスに分岐させるステートメントです。

このメトリクスの推奨上限は 10 です。循環的複雑度が高い場合、コードは可読性が低く、かつオレンジ チェックが増加する可能性があります。したがって、このメトリクスの値を制限するようにしてください。

メトリクスに制限を適用するには、Polyspace を使用したコード複雑度メトリクスの計算を参照してください。

計算の詳細

メトリクスの計算では、次のルールを使用して判定点を特定します。

  • if ステートメントは 1 つの判定点です。

  • ステートメント forwhile は、条件が評価されない場合 (たとえば、無限ループ内) でも、1 つの判定点としてカウントします。

  • boolean の結合 (&&, ||) は判定点としてカウントしません。

  • case ステートメントは、その後に break ステートメントが続かない限り、判定点としてカウントしません。たとえば、次のコードは循環的複雑度 3 になります。

    switch(num) {
    		case 0:
    		case 1:
    		    break;
    		case 2:
    		    break;
    		case 3:
    		case 4:
    	}
    	

    オプション -consider-switch-as-single-decision を指定すると、Polyspace®switch-case ステートメント全体を単一判定点と見なし、上記のコードの循環的複雑度は 2 になります。

  • 計算は次の前処理後に実行されます。

    • マクロが展開されます。

    • 条件付きのコンパイルが適用されます。前処理命令で隠されたブロックは無視されます。

すべて展開する

int foo(int x,int y)
{
    int flag;
    if (x <= 0)
        /* Decision point 1*/
        flag = 1;
    else
    {
        if (x < y )
            /* Decision point 2*/
            flag = 1;
        else if (x==y)
            /* Decision point 3*/
            flag = 0;
        else
            flag = -1;
    }
    return flag;
}

この例では、foo の循環的複雑度は 4 です。

int foo (int x, int y) {
    if((x <0) ||(y < 0))
        /* Decision point 1*/
        return 0;
    else
        return (x > y ? x: y);
        /* Decision point 2*/
}

この例では、foo の循環的複雑度は 3 です。? 演算子は 2 番目の判定点です。

#include <stdio.h>


int foo(int x,int y, int ch)
{
    int val = 0;
    switch(ch) {
    case 1:
        /* Decision point 1*/
        val = x + y;
        break;
    case 2:
        /* Decision point 2*/
        val = x - y;
        break;
    default:
        printf("Invalid choice.");
    }
    return val;
}

この例では、foo の循環的複雑度は 3 です。

int foo(int x,int y, int bound)
{
    int count = 0;
    if (x <= y)
        /* Decision point 1*/
        count = 1;
    else
        while(x>y) {
            /* Decision point 2*/
            x--;
            if(count< bound) {
                /* Decision point 3*/
                count++;
            }
        }
    return count;
}

この例では、foo の循環的複雑度は 4 です。

この例では、関数 factorial() が switch-case ステートメントを使用して戻り値を選択します。

int factorial(int in) {
	int val = -1;
	switch(in) {
		case 1:
			val = 1;
			break;
		case 2:
			val = 2;
			break;
		case 3:
			val = 6;
			break;
		default:
			break;
	}
	return val;
}
既定では、Polyspace は循環的複雑度の値を 4 と報告します。オプション -consider-switch-as-single-decision を指定すると、Polyspace は switch-case ステートメント全体を単一判定点と見なし、その結果、循環的複雑度は 2 になります。

メトリクス情報

グループ: 関数
頭字語: VG
HIS メトリクス:あり