MISRA C:2012 Rule 14.2

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

Описание

Примечание

Используйте Bug Finder вместо Code Prover для проверки правил кодирования. Поддержка кодирования правил, регистрируясь в Code Prover будет удалена в будущем релизе. См. Вопросы совместимости.

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

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

Объяснение

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

Реализация Polyspace

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

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

  • Второй пункт не содержит операцию сравнения, включающую счетчик цикла.

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

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

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

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

Если вы ожидаете нарушение правила, но не видите его, относитесь, чтобы Диагностировать, Почему Кодирующие Стандартные Нарушения Не Появляются как ожидалось.

Примеры

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

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: удобочитаемость

Вопросы совместимости

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

Не рекомендуемый запуск в R2021b