Правило 15.3 MISRA C:2012

Любая метка, на которую ссылается оператор перехода, должна быть объявлена в том же блоке, или в любом блоке, заключающем оператор перехода

Описание

Управляйте определением

Любая метка, на которую ссылается оператор перехода, должна быть объявлена в том же блоке, или в любом блоке, заключающем оператор перехода.

Объяснение

Неограниченное использование операторов goto делает программу неструктурированной и трудной понять. Ограничение использования операторов goto, чтобы перейти между блоками или во вложенные блоки уменьшает визуальную сложность кода.

Обменивайтесь сообщениями в отчете

Любая метка, на которую ссылается оператор перехода, должна быть объявлена в том же блоке, или в любом блоке, заключающем оператор перехода.

Поиск и устранение проблем

Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.

Примеры

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

void f1(int a) {
    if(a <= 0) {
        goto L2;        /* Non-compliant - L2 in different block*/
    }
    
    goto L1;            /* Compliant - L1 in same block*/

    if(a == 0) {
        goto L1;        /* Compliant - L1 in outer block*/
    }

    goto L2;            /* Non-compliant - L2 in inner block*/

    L1: if(a > 0) {
            L2:;
    }
}

В этом примере операторы goto вызывают скачки к различным меткам. Правило нарушено когда:

  • Метка происходит в блоке, отличающемся от блока, содержащего оператор goto.

    Блок, содержащий метку не, заключает и не заключен текущим блоком.

  • Метка происходит в блоке, заключенном блоком, содержащим оператор goto.

Правило не нарушено когда:

  • Метка происходит в том же блоке как блок, содержащий оператор goto..

  • Метка происходит в блоке, который заключает блок, содержащий оператор goto..

void f2 ( int x, int z ) {
    int y = 0;

    switch(x) {
    case 0:
        if(x == y) {
            goto L1;  /* Non-compliant - switch-clauses are treated as blocks */
        }
        break;
    case 1:
        y = x;
        L1: ++x;
        break;
    default:
        break;
    }

}

В этом примере метка для оператора goto, кажется, происходит в блоке, который заключает блок, содержащий оператор goto. Однако в целях этого правила, программное обеспечение полагает, что каждый оператор case начинает новый блок. Поэтому оператор goto нарушает правило.

Проверяйте информацию

Группа: Поток управления
Категория: необходимый
Категория AGC: консультация
Язык: C90, C99

Введенный в R2014b