parts/6.05.EnumeratorIssues-CCB.md

6.5 Enumerator Issues [CCB]

6.5.1 Applicability to language

The vulnerability documented in ISO IEC 24772-1 clause 6.5 applies to C++, as C++ allows the specification of the values underlying the enumerators.

C++ provides scoped (enum class) and unscoped (enum) enumeration types, where an underlying integral type can be specified. Unscoped enumeration types without an enum-base have a non-fixed underlying type that only guarantees values in the range of the provided enumerators are valid. The latter can cause non-representable values to be assigned to a variable of such an unscoped enumeration type. For enumeration types with a fixed underlying type all values of the underlying integral type are valid. See ISO IEC 24772-3 for vulnerabilities associated with unscoped enums with no fixed underlying type, except an explicit conversion is required to convert an integer to an enumeration type object.

Casting a value to an enumeration type is undefined behavior [EWF] unless the source value is within the range of values of an enumeration type. See CERT INT50-CPP. (remove CERT reference???)

enum Color  {red=1, green, blue};
short i = red; // implicit conversion
Color g { Color(green + blue) }; // Undefined-defined behaviour since 5 will not fit into
                                 // the smallest bitfield to hold red, green and blue

C++ does not support implicit conversion of a scoped enum to other types, hence, operations (such as arithmetic operations) must be explicitly provided.

In the following example, based upon the above definition,

void foo () { 
  i + red ;        // well-formed for unscoped enum, ill-formed for scoped enum.
}

Scoped enums, on the other hand, require that the conversions to/from the enumeration type must be explicit, as shown below:

enum class Color : short { red, green, blue };
short i = static_cast<short>(Color::red);

Color operator+(Color a, short b)
{
   return static_cast<Color>((static_cast<short>(a) + b) % 3);
}

Unscoped enumeration types implicitly promote to an integral type and can be used as the index of an array without a cast. Without a user-specified mapping to an underlying representation, there will be “holes” as documented in ISO IEC 24772-1:2024 clause 6.5 and ISO IEC TR 24772-3 clause 6.5.

6.5.2 Avoidance mechanisms for language users

To avoid the vulnerability or mitigate its ill effects, C++ software developers can: