メインコンテンツ

AUTOSAR C++14 Rule A4-5-1

Expressions with type enum or enum class shall not be used as operands to built-in and overloaded operators other than the subscript operator [], the assignment operator =, the equality operators == and !=, the unary & operator, and the relational operators <, <=, >, >=

説明

ルール定義

enum 型または enum クラスを含む式は、添字演算子 []、代入演算子 =、等号演算子 == および !=、単項 & 演算子、および関係演算子 <、<=、>、>= 以外の組み込み演算子とオーバーロードされた演算子に対するオペランドとして使用しないものとします。

根拠

C++ では、enumenum class などの列挙は処理系定義の動作をします。たとえば、これらの潜在型は、shortchar などの任意の整数型にすることができます。列挙を +- などの算術演算子のオペランドとして使用すると、列挙が潜在型に変換されます。列挙の潜在型は実装に依存するため、列挙をオペランドとして使用した算術演算の結果は予測不能です。予測不能で移植不能なコードを回避するには、列挙を次の演算子のオペランドとしてのみ使用します。

  • 添字演算子 []

  • 代入演算子 =

  • 等号演算子 == および !=

  • 単項 & 演算子

  • 関係演算子 <, <=,>,>=

列挙は、上記の演算子の組み込みインスタンスまたはオーバーロードされたインスタンスのオペランドとしてのみ使用できます。ビットマスク型の列挙はこのルールに対する例外であることに注意してください。つまり、ビットマスク型の列挙は任意の演算子のオペランドとして使用できます。

Polyspace 実装

列挙は、上記の演算子のオペランドとしてのみ有効です。Polyspace® は、他の演算子のオペランドとして使用された列挙にフラグを設定します。Polyspace は、BitmaskType 列挙の例外を認めないことに注意してください。

トラブルシューティング

ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

#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); は、2 つの列挙子を加算して、その結果を enum オブジェクト bitmask1 に代入します。加算演算では、列挙子が暗黙的に潜在型に変換されます。列挙子の潜在型は実装に依存するため、このコードの結果は予測不能になる可能性があります。Polyspace は、組み込み + 演算子のオペランドである列挙子にフラグを設定します。

Polyspace は、組み込み演算子とオーバーロードされた演算子の両方を同様に扱います。たとえば、Polyspace は、+ 演算子が enum class Car に対してオーバーロードされている場合でも、演算 Car::Model1 + Car::Model2 内のオペランドにフラグを設定します。

チェック情報

グループ: 標準変換
カテゴリ: Required、Automated

バージョン履歴

R2020a で導入