Main Content

MISRA C++:2023 Rule 10.2.1

An enumeration shall be defined with an explicit underlying type

Since R2024b

Description

Rule Definition

An enumeration shall be defined with an explicit underlying type.

Rationale

If the underlying type of an enumeration is not large enough to accommodate all the values of the enumerators, some enumerators might overflow. The values of these overflowing enumerator might be narrowed to values that already represent other enumerators, resulting in unexpected behavior.

To avoid unexpected narrowing, use appropriate underlying types for enumerations. An underlying type is appropriate if it satisfies all of these requirements:

  • The underlying type is explicitly specified.

  • All expressions defining values for the enumerators can be converted to the underlying type without any narrowing.

  • No enumerator value is too big to be represented by the underlying type.

As exceptions, explicitly specifying an underlying type is not required for these two cases:

  • All the enumerators in an enumeration use their default values:

    enum class defaultEnum{
       E0,
       E1,
       E3
    };
    Here, all the enumerators of defaultEnum use their default values since no values are specified for any of the enumerators. For these kinds of enumerations, the underlying type is not important.

  • An enumeration is declared in an extern "C" block:

    extern "C"{
       enum CStyleEnum{
          E1 = 0,
          E2,
          E3
       };
    }
    Enumerations declared within extern "C" blocks are intended to be used with C code, where this rule does not apply.

Polyspace Implementation

Polyspace® reports violations of this rule if either of these situations occurs:

  • You declare an enumeration without explicitly specifying an underlying type.

  • You declare an underlying type for the enumeration but at-least one of its enumerators are out of range for the specified underlying type.

As exceptions, Polyspace does not report violations for these two scenarios:

  • All the enumerators of an enumeration use their default value.

  • The enumeration is declared within an extern "C" block.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

In this example, Polyspace reports two violations.

#include <cstdint>

enum class myEnum1 { //Noncompliant- No underlying type
	E1 = 0,
	E2 = 14,
	E3 = 8
};

enum class myEnum2 : std::uint8_t { //Compliant
	E1 = 0,
	E2 = 1,
	E3 = 2
};

enum class myEnum3 : std::uint8_t { 
	E1 = 0,
	E2 = 1,
	E3 = 2000 //Noncompliant - type too small
};

enum class myEnum4 { //Compliant by exception- all enumerators use default values
	E1,
	E2,
	E3
};

extern "C" {
	enum  myEnum5 { //Compliant by exception- C linkage
		E1,
		E2,
		E3
	};
}

  • enum class myEnum1 is declared without explicitly specifying an underlying type. Polyspace reports a violation.

  • enum class myEnum2 has an underlying type that is large enough to accommodate all of its enumerator values. This enumeration is compliant with the rule..

  • enum class myEnum3 has an underlying type that is too small to accommodate the enumerator E3. Polyspace reports a violation.

  • enum class E4 lacks an explicitly specified underlying type, but because all of the enumerators of E4 use default values, this enumeration is compliant by exception.

  • E5 lacks an explicitly specified underlying type, but because it is declared with C linkage, it is compliant by exception.

In this example, Polyspace reports a violation when the anonymous enumeration is declared without an underlying type.

#include <cstdint>
namespace g3199043 {
	enum {                // Noncomplioant
		A = 0,
		B
	};

	enum : uint8_t  {         // Compliant
		X = 0,
		Y
	};
}
The compliant anonymous enumeration is declared using an underlying type.

Check Information

Group: Declarations
Category: Required

Version History

Introduced in R2024b