MISRA Discussion Forums

Full Version: 10.3 and storing enums in integers
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Looking at the table for rule 10.1, the essential type of an enum and an unsigned integer differ, and rule 10.3 states that "The value of an expression shall not be assigned to an object with a
narrower essential type or of a different essential type category". I would think that means that you can not assign an enum to a signed or unsigned integer type, but the example section shows this as not violating the rule:

s8a = K1;    /* Constant value fits */

Why is this OK?
This is alright because K1 is declared as an anonymous enumeration type enum { K1=1, K2=128 };

Section 8.10.2 lists the possible essential type categories. This includes the following note.
Quote: Another exception is the use of anonymous enumerations as defined in Appendix D. Anonymous enumerations are a way of defining a set of related constant integers and are consider to have an essentially signed type.
Appendix D.5 gives the definition of anonymous enum type as
Quote:An anonymous enum type is an enumeration which does not have a tag and which is not used in the definition of any object, function or type.
Appendix D.6 gives the type of anonymous enum constants as
Quote:The following anonymous enum type defines a set of constants. The essential type of each constant is the STLR. Therefore on a machine with 8-bit char and 16-bit short types, A and B have an essential type of signed char but C has an essential type of signed short.
enum { A = 8, B = 64, C = 128 };
The essential type of the K1 enumeration constant is therefore determined as the STLR of the literal "1", which means that the essential type of K1 is signed char.
And if the enum *is* given a tag, that changes K1 into essentially enum type? Why?
Enumeration types can be used in a variety of ways, but the MISRA-C working group decided that there were two distinct uses.

1. The members of the enumerated type form a set distinct from another enumeration type, such that an object of that type should not be assigned a value of a different enumeration type or to any other type. This allows the extension of MISRA strict typing to enumerated types. A cast must be used if the integer value of the enumeration constant is required.

2. The members of the enumerated type form a set of integer constants which are used in essentially integer contexts. No cast is required if the integer value of the enumeration constant is required.

The rationale was that if you could create an object with an enumerated type, then that object should have a type distinct from an object with a different enumeration type. This is the MISRA named enumeration type. However it was recognised that a common usage case was to use enumeration types as a way of holding a set of integer constants and that it would be annoying to be forced to write a cast each time such a constant was used. This is the MISRA anonymous enumeration type.

The C standard does not give a way of distinguishing between these uses and therefore the MISRA-C working group imposed a convention on the C syntax. The presence of a tag in the enum declaration would enable an object to be declared with that type some-where else in the code. Removing the tag means that only the enumeration constants can be used and it was for this reason that the MISRA-C working group restricted this syntactic form to be an anonymous enumeration type.

Note: An object which is declared at the same time as an enumeration type with no tag is considered to be a named enumeration type.
e.g. enum{A,B,C} my_object;