AUTOSAR C++14 Rule A6-5-3

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

Описание

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

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

Объяснение

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 оператор, в то время как 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