MISRA Discussion Forums
M5-0-4 switch over unscoped enum without fixed underlying type - Printable Version

+- MISRA Discussion Forums (https://forum.misra.org.uk)
+-- Forum: MISRA C++ (https://forum.misra.org.uk/forumdisplay.php?fid=18)
+--- Forum: MISRA C++:2008 rules (https://forum.misra.org.uk/forumdisplay.php?fid=19)
+---- Forum: 6.5 Expressions (C++) (https://forum.misra.org.uk/forumdisplay.php?fid=134)
+---- Thread: M5-0-4 switch over unscoped enum without fixed underlying type (/showthread.php?tid=1785)



M5-0-4 switch over unscoped enum without fixed underlying type - cgpzs - 16-09-2026

Hi,

Our static analyzer is flagging this code:

Code:
// third_party.h
typedef enum
{
  FOO_A,
  FOO_B
} Foo;

// main.cpp
#include <third_party.h>

int get(Foo x)
{
  switch(x)            // Non-compliant with M5-0-4 ?
  {
    case FOO_A:        // Non-compliant with M5-0-4 ?
      return 123;
    case FOO_B:        // Non-compliant with M5-0-4 ?
      return 321;
  }
  return -1;
}

The rationale from the supplier is:
  • "Foo" is an unscoped enum without fixed underlying type.
  • Thus, its underlying type is implementation-defined.
  • On this implementation, the actual type is "unsigned int".
  • The line with "switch(x)" performs an integral promotion of "x" to "int", thus changing the signedness from "unsigned int" to "int".
  • Similarly, the "case FOO_*" lines also perform an integral promotion to "int".
  • This change in signedness is a violation of M5-0-4.

We argue however that the code is perfectly safe and idiomatic, the Standard guarantees that the conversion is made to an integer able to hold all the values of the enumerator, so it's impossible for data loss to occur.

What is your opinion, is M5-0-4 truly applicable in this case?

Thanks!


RE: M5-0-4 switch over unscoped enum without fixed underlying type - misra cpp - 18-09-2026

The short answer is that as far as M5-0-4 is concerned, all aspects of your switch statement are compliant.

The M in M5-0-4 means that this Autosar rule is taken directly from MISRA C++:2008 "An implicit integer conversion shall not change the signedness of the underlying type".  "underlying type" is in italics, meaning its using the MISRA definition of the term, NOT the C++ language definition. Under the MISRA definition, an enum is not an integer type, its underlying type is itself (Foo). So the switch statement is performing comparisons between  x (of underlying type Foo) and enum values (FOO_A etc.) also of underlying type Foo - there are therefore no conversions, so the rule does not apply.

This MISRA definition of "underlying type" proved both confusing and unpopular and has been removed from subsequent versions of both MISRA C and C++. 

We've looked at the equivalent rule in MISRA:2023. Again, your specific example would be compliant, but if the example is changed so the unscoped enum has an underlying type (as per the C++ language definition), then the code may be non-compliant (depending upon the signedness). This wasn't the intension, so has been added as an issue to be addressed.


RE: M5-0-4 switch over unscoped enum without fixed underlying type - cgpzs - 21-09-2026

Thank you for the clarification! Will report back to our supplier.

By the way, would the same rationale apply here?

Code:
std::int32_t x = ...;
x = FOO_A;        // Compliant with M5-0-4?

if (x == FOO_A)   // Compliant with M5-0-4?

In other words since `FOO_A` is of "enum type", does that mean the rule does not apply at all?


RE: M5-0-4 switch over unscoped enum without fixed underlying type - misra cpp - 25-09-2026

We believe that that is the correct literal interpretation of the rules, though possibly not the intension.