Enumeration types in C map to integers. The normal expectation is that each enumeration type member is distinct. However, there are some non-obvious errors that are commonly made that cause multiple enumeration type members to have the same value.

Non-Compliant Code Example

In this non-compliant code example, enumeration type members can be assigned explicit values:

enum {red=4, orange, yellow, green, blue, indigo=6, violet};

It may not be obvious to the programmer (though it is fully specified in the language) that yellow and indigo have been declared to be identical values (6), as are green and violet (7).

Compliant Solution

Enumeration type declarations must either

enum {red, orange, yellow, green, blue, indigo, violet};
enum {red=4, orange, yellow, green, blue, indigo, violet};
enum {
  red=4, 
  orange=5, 
  yellow=6, 
  green=7, 
  blue=8, 
  indigo=6, 
  violet=7
};

It is also advisable to provide a comment explaining why multiple enumeration type members are being assigned the same value so that future maintainers don't mistakenly identify this as an error.

Of these three options the first "provide no explicit integer assignments" is the simplest, and consequently the preferred approach in the typical case.

Risk Assessment

Failing to ensure that constants within an enumeration have unique values can result in unexpected logic results.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

INT09-A

low

unlikely

low

P3

L3

Automated Detection

The LDRA tool suite V 7.6.0 is able to detect violations of this recommendation.

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]\] Section 6.7.2.2, "Enumeration specifiers"
\[[ISO/IEC PDTR 24772|AA. C References#ISO/IEC PDTR 24772]\] "CCB Enumerator issues"
\[[MISRA 04|AA. C References#MISRA 04]\] Rule 9.3


INT08-A. Verify that all integer values are in range      04. Integers (INT)       INT10-A. Do not assume a positive remainder when using the % operator