AUTOSAR C++14 Rule A4-5-1

Выражения с типом enum или классом enum не должны использоваться как операнды для встроенных и перегруженных операторов, кроме оператора индекса [], оператора назначения =, операторов равенства = = и! =, унарного & оператора и реляционных операторов <, < =, >, > =

Описание

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

Выражения с типом enum или классом enum не должны использоваться как операнды для встроенных и перегруженных операторов, кроме оператора индекса [], оператора присвоения =, операторов равенства = = и! =, унарного & оператора и реляционных операторов <, < =, >, > =.

Объяснение

В C++ перечисления, такие как enum или enum class имеют определенные реализации поведения. Например, их базовым типом может быть любой интегральный тип, включая short или char. Если вы используете перечисления как операнды для арифметических операторов, таких как + или -они преобразуются в базовый тип. Поскольку базовый тип перечисления зависит от реализации, результат арифметических операций, использующих перечисления как операнды, непредсказуем. Чтобы избежать непредсказуемого и нетранспортабельного кода, используйте перечисления как операнды только для этих операторов:

  • Опции оператора индекса []

  • Оператор назначения =

  • Операторы равенства == и !=

  • Унарное & оператор

  • Реляционные операторы <, <=,>,>=

Перечисления можно использовать как операнды для встроенных или перегруженных образцов только вышеописанных операторов. Обратите внимание, что перечисления типов Bitmask являются исключением из этого правила. То есть можно использовать перечисления типов Bitmask как операнды любым операторам.

Реализация Polyspace

Перечисления являются допустимыми операндами только для перечисленных выше операторов. Polyspace® флаги перечисления, когда они используются как операнды для любых других операторов. Обратите внимание, что Polyspace не делает исключения для перечислений BitmaskType.

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

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

Примеры

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

#include <cstdint>
enum Color : std::uint8_t {  Red,  Green,  Blue,  ColorsCount};
enum class Car : std::uint8_t { Model1, Model2, Model3, ModelsCount};
enum BMT {Exec = 0x1,Write  = 0x2,Read = 0x4};
Car operator+(Car lhs, Car rhs)
{
	return Car::Model3;
}
Color operator|=(Color lhs, Color rhs)
{
	return rhs;
};
void F1() 
{
	Car car = Car::Model1;
	Color color = Red;
	if (color == Green) {                   // Compliant
	}

	if (color == (Red + Blue)) {            // Noncompliant 
	}

	if (color < ColorsCount) {              //Compliant
	}
	if (car == (Car::Model1 + Car::Model2)) // Noncompliant 
	{
	}
	Color value;
	value = (Color)(Red | 3);               // Noncompliant
	value |= Blue;                          // Noncompliant 
	value = (Color)0;                       // Compliant
	if (value & Blue) {};                   // Noncompliant 
	value = (Color)(Blue * value       );   // Noncompliant 
	value = (Color)(Red << 3);              // Noncompliant
	value = (Color)(Red >> 12);             // Noncompliant
	BMT bitmask1 = (BMT)(Exec + Write);     // Noncompliant 
	BMT bitmask2 = (BMT)(Exec | Write);     // Noncompliant 
}

Область линии BMT bitmask1 = (BMT)(Exec + Write); добавляет два перечислителя и присваивает результат enum bitmask1 объекта. Операция сложения неявно преобразует перечислители в их базовый тип. Поскольку базовый тип перечислителей зависит от реализации, результат этого кода может быть непредсказуемым. Polyspace помечает перечислители, которые являются операндами встроенного + оператор.

Polyspace одинаково обрабатывает как встроенных, так и перегруженных операторов. Например, Polyspace помечает операнды в операции Car::Model1 + Car::Model2, хотя + оператор перегружен для enum class Car.

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

Группа: Стандартные преобразования
Категория: Необходимый, Автоматизированный
Введенный в R2020a