exponenta event banner

Правило AUTOSAR C++ 14 A4-5-1

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

Описание

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

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

Объяснение

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

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

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

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

  • Одноместное & оператор

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

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

Внедрение 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