exponenta event banner

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

Контур «для» должен быть хорошо сформирован

Описание

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

Контур «для» должен быть хорошо сформирован.

Объяснение

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 цикл со всеми тремя предложениями пустой, чтобы разрешить бесконечные циклы.

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

Группа: Выражения управляющих операторов
Категория: Обязательно
Категория СМЖЛ: удобочитаемость