AUTOSAR C++14 Rule A6-5-3

Операторы Do не должны использоваться

Описание

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

Операторы Do не должны использоваться.

Объяснение

A do оператор может ввести ошибки в ваш код, потому что его условие завершения проверяется после выполнения блока кода. Рассмотрим этот код, где доступ к массиву осуществляется с помощью указателя в do-while цикл.

int* array;
//...
do {
cout<<*array;
--array;
} while (array != nullptr); 
Поскольку условие завершения проверяется после выполнения блока кода, этот код может аннулировать дефект недопустимого или нулевого указателя, который может неожиданно прекратить выполнение кода во время выполнения. Код также трудно считать, потому что условие выполнения блока находится в конце блока, где его можно легко пропустить.

Избегайте do операторы в коде. Можно использовать do операторы для записи функциональных макросов.

Реализация Polyspace

Polyspace® флаги все do операторы, кроме тех, которые расположены в макросах.

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

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

Примеры

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

В этом примере показано, как Polyspace флаги do операторы вне макроса. Этот код использует указатель в do-while цикл. Завершающим условием является то, что указатель не является указателем на значение NULL.

#include<cstdint>
struct P
{
	int val;
	struct P* next;
};

void psKO(P*p)
{
	do              // Noncompliant
	{
		p = p->next;
	} while(p!=nullptr);
}

Этот код может аннулировать пустой указатель, потому что завершающее условие проверяется после выполнения do блок. Код также трудно считать, потому что условие завершения помещено в конец блока. Polyspace помечает do оператор.

Этот пример показывает, как Polyspace лечит do операторы в макросе. Рассмотрим этот код, где два макроса, SWAP и SWAP2 реализованы. SWAP использует do оператор в то время как SWAP2 не делает.

#include <cstdint>
//Compliant by exception 
#define SWAP(a, b) \
        do                         \
        {                          \
            decltype(a) tmp = (a); \
           (a) = (b);             \
           (b) = tmp;             \
       } while (0)

#define SWAP2(a, b)        \
       decltype(a) tmp = (a); \
       (a) = (b);             \
       (b) = tmp;

int main(void)
{
  uint8_t a = 24;
  uint8_t b = 12;

  if (a > 12)
//  SWAP2(a, b);  // Compilation Error
  SWAP(a, b);
return 0;
}

Эти два макроса предназначены для вызова как функции. Вы не можете использовать SWAP2 как функциональный макрос в if блок, потому что после расширения, только первый оператор выражения SWAP2 остается в пределах if блок. Это распад макроса меняет его смысл, и в этом случае вызывает ошибку компиляции. Решение этой проблемы состоит в том, чтобы заключить макрос в do-while заблокировать и поместить условие завершения как ложное. Такие вложенные макросы не могут быть разбиты и могут быть вызваны как функции. Polyspace не помечает do операторы в макросах.

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

Группа: Операторы
Категория: Консультационные, Автоматизированные
Введенный в R2020b