exponenta event banner

Недоступный код

Код не выполнен из-за предыдущих инструкций control-flow

Описание

Этот дефект возникает, когда раздел кода не может быть достигнут из-за предыдущего разрыва в потоке управления.

Заявления, такие как break, goto, и returnпереместите поток выполнения программы в другой раздел или функцию. Из-за этого отхода потока операторы, следующие за кодом управляющего потока, статистически не выполняются, и, следовательно, операторы недоступны.

Эта проверка также находит код после тривиальных бесконечных циклов, таких как while(1). Эти типы циклов освобождают поток программы только путем выхода из программы. Этот тип выхода приводит к недоступности кода после бесконечного цикла.

Риск

Недостижимый код тратит время разработки, память и циклы выполнения. Разработчики должны поддерживать код, который не выполняется. Команды, которые не выполняются, по-прежнему должны храниться и кэшироваться.

Зафиксировать

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

Если вы не хотите устранять проблему, добавьте комментарии к результату или коду, чтобы избежать другой проверки. См. раздел Результаты анализа пространства адресов с помощью исправлений ошибок или обоснований.

Примеры

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

typedef enum _suit {UNKNOWN_SUIT, SPADES, HEARTS, DIAMONDS, CLUBS} suit;
suit nextcard(void);
void guess(suit s);

suit deal(void){
    suit card = nextcard();
    if( (card < SPADES) || (card > CLUBS) ) 
        card = UNKNOWN_SUIT;
        return card;

    if (card < HEARTS) {
        guess(card);
    }
    return card;
}

В этом примере отсутствуют фигурные скобки и вводящие в заблуждение отступы. Первое return оператор изменяет поток кода обратно в место вызова функции. Из-за этой инструкции return if-блочный и второй return оператор не выполняется.

Если исправить отступы и раскосы, ошибка станет более ясной.

typedef enum _suit {UNKNOWN_SUIT, SPADES, HEARTS, DIAMONDS, CLUBS} suit;
suit nextcard(void);
void guess(suit s);

suit deal(void){
    suit card = nextcard();
    if( (card < SPADES) || (card > CLUBS) ){ 
        card = UNKNOWN_SUIT;
    }
    return card;

    if (card < HEARTS) {
        guess(card);
    }
    return card;
}

Исправление - удаление возврата

Одним из возможных исправлений является удаление инструкции escape. В этом примере удалите первый return заявление для выхода в финал if заявление.

typedef enum _suit {UNKNOWN_SUIT, SPADES, HEARTS, DIAMONDS, CLUBS} suit;
suit nextcard(void);
void guess(suit s);

suit deal(void){
    suit card = nextcard();
    if( (card < SPADES) || (card > CLUBS) )
    {
        card = UNKNOWN_SUIT;
    }

    if(card < HEARTS)
    {
        guess(card);
    }
    return card;
}
Исправление - удаление недоступного кода

Другое возможное исправление - удалить недостижимый код, если он вам не нужен. Поскольку функция не достигает второй if-statement, удаление которого упрощает код и не изменяет поведение программы.

typedef enum _suit {UNKNOWN_SUIT, SPADES, HEARTS, DIAMONDS, CLUBS} suit;
suit nextcard(void);
void guess(suit s);

suit deal(void){
    suit card = nextcard();
    if( (card < SPADES) || (card > CLUBS) )
    {
        card = UNKNOWN_SUIT;
    }
    return card;
}
int add_apples(int apple) { 
    int count = 1;
    while(1) {
        if(apple < 99){
            apple++; 
            count++;
        }else{
            count--;
        }
    }
    return count;
}

В этом примере while(1) оператор создает бесконечный цикл. return count Оператор, следующий за этим бесконечным циклом, недоступен, потому что единственный способ выйти из этого бесконечного цикла - выйти из программы.

Исправление - условие перезаписи цикла

Одной из возможных корректировок является изменение условия цикла для выполнения while петля конечная. В приведенном примере исправления цикл использует оператор из if состояние: apple < 99.

int add_apples1(int apple) { 
    int count = 0;
    while(apple < 99) { 
        apple++; 
        count++;
    }
    if(count == 0)
        count = -1;
    return count;
}
Исправление - Добавление выписки о разрыве

Другой возможной поправкой является добавление разрыва из бесконечного цикла, так что существует возможность достижения кода после бесконечного цикла. В этом примере break добавляется к else блок, образующий return count оператор доступен.

int add_apples(int apple) { 
    int count = 1;
    while(1) {
        if(apple < 99)
        {
            apple++; 
            count++;
        }else{
            count--;
            break;
        }
    }
    return count;
}
Исправление - удаление недоступного кода

Другой возможной поправкой является удаление недостижимого кода. Это исправление очищает код и упрощает его просмотр и ведение. В этом примере удалите оператор return и измените тип возврата функции на void.

void add_apples(int apple) { 
    int count = 1;
    while(1) {
        if(apple < 99)
        {
            apple++; 
            count++;
        }else{
            count--;
        }
    }
}

Информация о результатах

Группа: Поток данных
Язык: C | C++
По умолчанию: Вкл.
Синтаксис командной строки: UNREACHABLE
Воздействие: среднее
CWE ID: 561
Представлен в R2013b