exponenta event banner

Правило AUTOSAR C++ 14 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 цикл. Условие завершения состоит в том, что указатель не является нулевым.

#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 оператор while 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