MISRA C:2012 Rule 14.2

Цикл for должен быть правильно построен

Описание

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

Цикл for должен быть правильно построен.

Объяснение

for оператор предоставляет услугу цикличного выполнения общего назначения. Используя ограниченную форму цикла делает код легче рассмотреть и анализировать.

Реализация Polyspace

Polyspace® проверяет что:

  • for индекс цикла (V) переменный символ.

  • V последняя присвоенная переменная в первом выражении (если есть).

  • Если первое выражение существует, оно содержит присвоение V.

  • Если второе выражение существует, это - сравнение V.

  • Если третье выражение существует, это - присвоение V.

  • Нет никаких прямых присвоений for индекс цикла.

Дополнительное сообщение в отчете

  • 1-е выражение должно быть присвоением. Следующие виды циклов for позволены:

    • должны присутствовать все три выражения;

    • 2-е и 3-и выражения должны присутствовать с предшествующей инициализацией счетчика цикла;

    • все три выражения должны быть пустыми для преднамеренного бесконечного цикла.

  • 3-е выражение должно быть присвоением счетчика цикла.

  • 3-е выражение: присвоенная переменная должна быть счетчиком цикла (counter).

  • 3-е выражение должно быть присвоением счетчика цикла (counter) только.

  • 2-е выражение должно содержать сравнение со счетчиком цикла (counter).

  • Счетчик цикла (counter) не должен быть изменен в теле цикла.

  • Плохо введите счетчик цикла for (counter).

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

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

Примеры

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

void foo(void){

    for(short index=0; index < 5; index++){  /* Non-compliant */
        index = index + 3;       /* Altering the loop counter */
    }
}

В этом примере, счетчик цикла index изменения в for цикл. Трудно определить, когда цикл завершает работу.

Коррекция — использует другую переменную, чтобы завершить работу рано

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

В этой коррекции, втором пункте for цикл зависит от встречного значения, index < 5, и на дополнительный флаг, !flag. С дополнительным флагом определение цикла for и счетчик остаются читаемыми, и можно выйти из цикла рано.

#define FALSE 0
#define TRUE  1

void foo(void){

    int flag = FALSE;

    for(short index=0; (index < 5) && !flag; index++){ /* Compliant */
        if((index % 4) == 0){
            flag = TRUE;        /* allows early termination of loop */
        }
    }
}
void foo(void){
    for(short index = 0; ; index++) {}   /* Non-compliant */

    for(short index = 0; index < 10;) {} /* Non-compliant */

    short index;
    for(; index < 10;) {}     /* Non-compliant */

    for(; index < 10; index++) {} /* Compliant */

    for(;;){}  
          /* Compliant - Exception all three clauses can be empty */
}

Этот пример показывает for определения циклов со множеством недостающих пунктов. Чтобы быть совместимыми, инициализируйте первую переменную пункта перед for цикл (линия 9). Однако у вас не может быть for цикл без второго или третьего пункта.

Одним исключением является for цикл со всеми тремя пустыми пунктами, чтобы допускать бесконечные циклы.

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

Группа: управляйте выражениями оператора
Категория: необходимый
Категория AGC: удобочитаемость