Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

到達不能コード

コードが実行中に到達できません。

説明

到達不能コードでは、ステートメント カバレッジを使用して、コードのセクションが実行中に到達できるかどうかが判別されます。ステートメント カバレッジは、プログラム ステートメントが実行されるかどうかをチェックします。ステートメントにテスト条件があり、そのうち 1 つ以上が発生する場合、そのステートメントは実行され、到達可能です。発生しないテスト条件は、対応するコード分岐がある場合を除いて、デッド コードと見なされません。すべてのテスト条件が発生しない場合、そのステートメントは実行されません。また、各テスト条件は到達不能コードのインスタンスです。たとえば、このコードの switch ステートメントにおいて、case 3 が発生することはありません。

void test1 (int a) {
	int tmp = 0;
	if ((a!=3)) {
		switch (a){
			case 1:
				tmp++;
				break;
			default:
				tmp = 1;
				break;
/* case 3 falls through to 
   case 2, no dead code */
			case 3:
			case 2:
				tmp = 100;
				break;
		}
	}
}

void test2 (int a) {
	int tmp = 0;
	if ((a!=3)) {
		switch (a){
			case 1:
				tmp++;
				break;
			default:
				tmp = 1;
				break;
// Dead code on case 3
			case 3:
				break;
			case 2:
				tmp = 100;
				break;
		}
	}
}

test1() では、case 3 に続いて case 2 が実行されるので、チェックではデッド コードが示されません。test2() では、次の行の break ステートメントが実行されないため、チェックでは case 3 のデッド コードが示されます。

到達不能コードの他の例には以下があります。

  • テスト条件が常に false に評価する場合、対応するコード分岐には到達できません。[ソース] ペインで、分岐の左中かっこはグレーになります。

  • テスト条件が常に true に評価する場合、条件は冗長です。[ソース] ペインで、if などの条件キーワードはグレーで表示されます。

  • コードの前に break または return ステートメントがある。

[ソース] ペインでコード ブロックの左中かっこがグレーで表示される場合、ブロック全体を強調表示するには、中かっこをダブルクリックします。

チェックは関数内のコードで動作します。[呼び出されていない関数] および[到達不能な関数] のチェックにより、関数自体が呼び出されていないか、もしくは到達不能コードから呼び出されているかが判定されます。

すべて展開する

#define True 1
#define False 0
 
typedef enum {
  Intermediate, End, Wait, Init
} enumState;
 
enumState input();
enumState inputRef();
void operation(enumState, int);
  
int checkInit (enumState stateval)  {
  if (stateval == Init) 
    return True;
  return False;
}
 
int checkWait (enumState stateval)  {
  if (stateval == Wait) 
    return True;
  return False;
}
  
void main()  {
  enumState myState = input(),refState = inputRef() ;
  if(checkInit(myState)){
    if(checkWait(myState)) {
      operation(myState,checkInit(refState));	
    } else {
      operation(myState,checkWait(refState));
    }
  }
} 

この例では、mainif(checkInit(myState)) の分岐に入るのは myState = Init の場合のみです。したがって、分岐内で Polyspace®myState には値 Init が含まれるとみなします。checkWait(myState) は常に False を返し、if(checkWait(myState)) の第 1 の分岐は到達不能です。

修正 — 冗長なテストを削除

1 つの修正方法として、冗長なテスト if(checkWait(myState)) を削除します。

#define True 1
#define False 0
 
typedef enum {
  Intermediate, End, Wait, Init
} enumState;
 
enumState input();
enumState inputRef();
void operation(enumState, int);

int checkInit (enumState stateval)  {
  if (stateval == Init) 
    return True;
  return False;
}
 
int checkWait (enumState stateval)  {
  if (stateval == Wait) return True;
  return False;
}
   
void main()  {
  enumState myState = input(),refState = inputRef() ;
  if(checkInit(myState))
    operation(myState,checkWait(refState));
} 
#include <stdlib.h>
#include <time.h>

int roll() {
  return(rand()%6+1);
}

void operation(int);
     
void main()   {
    srand(time(NULL));
    int die = roll();
    if(die >= 1 && die <= 6)
      /*Unreachable code*/
      operation(die);
  }

この例では、roll() は 1 と 6 の間の値を返します。したがって、main での if テストは常に true と評価され、冗長となります。対応する else 分岐がある場合、else ステートメントにグレー エラーが表示されます。ここでは else 分岐がないため、グレー エラーが if キーワード上に表示されて、冗長状況を示します。

修正 — 冗長なテストを削除

1 つの修正方法として、条件 if(die >= 1 && die <=6) を削除します。

#include <stdlib.h>
#include <time.h>

int roll() {
  return(rand()%6+1);
}

void operation(int);
     
void main()   {
  srand(time(NULL));
  int die = roll();
  operation(die);
}
#include <stdlib.h>
#include <time.h>
#define True 1
#define False 0

int roll1() {
  return(rand()%6+1);
}

int roll2();
void operation(int,int);
    
void main()   {
  srand(time(NULL));
  int die1 = roll1(),die2=roll2();
  if((die1>=1 && die1<=6) || 
     (die2>=1 && die2 <=6))
  /*Unreachable code*/
    operation(die1,die2);
}

この例では、roll1() は 1 と 6 の間の値を返します。したがって、if テストの最初の部分である if((die1>=1) && (die1<=6)) は常に true となります。if テストの 2 つの部分は || で結合されているため、if テストは、2 番目の部分に関わりなく常に true になります。したがって、if テストの 2 番目の部分は到達不能です。

修正 — テストを && で結合

1 つの修正方法として、|| ではなく && によって if テストの 2 つの部分を結合するとします。

#include <stdlib.h>
#include <time.h>
#define True 1
#define False 0

int roll1() {
  return(rand()%6+1);
}

int roll2();
void operation(int,int);
    
void main()   {
  srand(time(NULL));
  int die1 = roll1(),die2=roll2();
  if((die1>=1 && die1<=6) && 
     (die2>=1 && die2<=6))
    operation(die1,die2);	
}

チェック情報

グループ: データ フロー
言語: C | C++
頭字語: UNR