Недостижимый код

Код не может быть достигнут во время выполнения

Описание

Недостижимый код использует покрытие оператора, чтобы определить, может ли раздел кода быть достигнут во время выполнения. Покрытие оператора проверяет, выполняется ли оператор программы. Если оператор имеет условия испытания, и по крайней мере один из них происходит, оператор выполняется и достижим. Условия испытания, которые не происходят, не рассматриваются мертвым кодом, если у них нет соответствующего ответвления кода. Если все условия испытания не происходят, оператор не выполняется, и каждое условие испытания является экземпляром недостижимого кода. Например, в операторах 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() проверка показывает мертвый код для case 3, потому что оператор break на следующей строке не выполняется.

Другие примеры недостижимого кода включают:

  • Если условие испытания всегда оценивает ко лжи, соответствующее ответвление кода не может быть достигнуто. На панели Source вводная фигурная скобка ответвления является серой.

  • Если условие испытания всегда оценивает к истине, условие избыточно. На панели Source ключевое слово условия, такое как if, кажется серым.

  • Код следует за оператором break или return.

Если вводная фигурная скобка блока кода кажется серой на панели Source, чтобы подсветить целый блок, дважды кликнуть фигурную скобку.

Проверка работает с кодом в функции. Function not called проверок и Function not reachable определяют, не вызвана ли сама функция или названа из недостижимого кода.

Примеры

развернуть все

#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));
    }
  }
} 

В этом примере main вводит ответвление if(checkInit(myState)) только если myState = Init. Поэтому в том ответвлении, Polyspace® полагает, что myState имеет значение Init. checkWait(myState) всегда возвращает False, и первое ответвление if(checkWait(myState)) недостижимо.

Исправление — удаляет избыточный тест

Одно возможное исправление должно удалить избыточный тест 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. Поэтому тест if в main всегда оценивает к истине и избыточен. Если существует соответствующее ответвление else, серая ошибка появляется на операторе else. Без ответвления else серая ошибка, кажется, на ключевом слове if указывает на избыточное условие.

Исправление — удаляет избыточный тест

Одно возможное исправление должно удалить условие 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)) всегда верен. Поскольку две части теста if объединены с ||, тест if всегда верен независимо от второй части. Поэтому вторая часть теста if недостижима.

Исправление — тесты объединения с &&

Одно возможное исправление должно объединить две части теста if с && вместо ||.

#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