AUTOSAR C++14 Rule A4-5-1

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

Описание

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

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

Объяснение

На 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;                       // Noncompliant
	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