MISRA C:2012 Rule 14.2

A для цикла должна быть хорошо сформирована

Описание

Определение правила

A для цикла должна быть хорошо сформирована.

Объяснение

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

Реализация Polyspace

Цикл for состоит из оператора управления с тремя предложениями и тела цикла. Шашка вызывает нарушение, если:

  • Первое предложение не содержит инициализацию (кроме случаев, когда предложение пустое). Чекер рассматривает последнюю назначенную переменную первого for-loop предложение как счетчик цикла. Если первое предложение пустое, средство проверки рассматривает переменную с шагом или уменьшением в третьем предложении как счетчик цикла.

  • Второе предложение не содержит операцию сравнения с использованием счетчика цикла.

  • Третье предложение содержит операцию, отличную от операции увеличения или уменьшения счетчика цикла (отделенная запятыми от шага или уменьшения).

  • Счетчик цикла имеет тип данных, который не является целым числом или типом указателя.

  • Счетчик цикла увеличивается в теле цикла.

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

Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».

Примеры

расширить все

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: Читаемость