V2661. MISRA. A 'for' loop should be well-formed.

Диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.

Правило актуально только для языка C.

Цикл for должен быть отформатирован в соответствии со следующими правилами:

Первый оператор цикла (Init-statement) должен:

Второй оператор (Condition) должен:

Третий оператор цикла (Expression) должен:

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

Примечание. Допустимо использовать цикл с тремя пустыми операторами for( ; ; ).

Рассмотрим пример некорректного кода:

for (size_t i = 0;
     i < users.size() && retry_count < MAX_RETRIES; // <=
     i += (retry_count > 0 ? 0 : 1))                // <=
{
  if (!checkUser(users[i])) 
  {
    retry_count += 1;        // <=
  } 
  else
  {
    retry_count = 0;         // <=
  }
  // ....
}

Опасность кода заключается в неочевидном зависании цикла на проблемном пользователе. Если функция checkUser постоянно возвращает false при обработке какого-то пользователя, цикл застревает на одной позиции, пока не исчерпает все попытки. Это приводит к пропуску всех последующих пользователей, что бывает сложно обнаружить при обзоре кода.

В данном случае правильное форматирование запрещает использование retry_count во втором и третьем операторе цикла for, поскольку эта переменная модифицируется в теле цикла. Чтобы исправить проблему, можно вынести механизм валидации в отдельную функцию. Тогда цикл будет работать предсказуемо и обрабатывать всех пользователей.

Исправленный код:

bool checkUserWithRetry(const std::string& user) {
    for (int attempt = 0; attempt < MAX_RETRIES; attempt++) {
        if (checkUser(user)) return true;
    }
    return false;
}
// ....
for (size_t i = 0; i < users.size(); i++) {
    if (!checkUserWithRetry(users[i])) {
        logError("Failed to process user: " + users[i]);
    }
}
// ....

Данная диагностика классифицируется как:

  • MISRA-C-2023-14.2