This rule is part of MISRA C++:2023.
Usage of this content is governed by Sonar’s terms and conditions. Redistribution is
prohibited.
Rule 10.2.3 - The numeric value of an unscoped enumeration with no fixed underlying type shall not be used
[dcl.enum] Implementation 7
Category: Required
Analysis: Decidable,Single Translation Unit
Amplification
In an evaluated context, expressions of unscoped enumeration type without a fixed underlying type shall not be used:
- As operands to an arithmetic, bitwise, shift, logical, or compound assignment operator;
- As operands to relational and equality operators, unless both operands have the same enumeration type;
- As the source of an assignment or a
static_cast, unless the target has the same enumeration type or is an integer type
large enough to accept all the values of the narrowest possible underlying type;
- As the condition of a
switch, unless all case constants are enumerators of the same enumeration.
Additionally, a static_cast expression shall only have an unscoped enumeration target type if that enumeration type has a
fixed underlying type.
Rationale
The underlying type of an unscoped enumeration that does not have a fixed underlying type is
implementation-defined, so any implicit conversion could yield surprising results.
Example
enum E { e1a, e1b };
enum Other { e2a };
void g( int32_t i );
void f( E e )
{
E e2 = e; // Compliant - assignment to the same type
int32_t i1 = e; // Compliant - assignment to a large enough integer
e == e1a; // Compliant
e < e1b; // Compliant
e == e2a; // Non-compliant - second operand of a different type
e + 1; // Non-compliant - addition
g( e ); // Compliant - assignment to large enough integer
switch( e ) // Non-compliant - cases are not all enumerators of E
{
case e1b: return; // e1b is an enumerator of E
case e2a: return; // e2a is not an enumerator of E
}
auto s = sizeof( e + 1 ); // Unevaluated context - rule does not apply
E e3 = static_cast< E >( 0 ); // Non-compliant
auto a1 = "QWERTY";
a1[ e1a ]; // Compliant - index operator
*( a1 + e1a ); // Non-compliant
std::string a2 { a1 };
a2[ e1a ]; // Compliant - assignment to a large enough integer (size_t)
}
Copyright The MISRA Consortium Limited © 2023