In question:
Why do I have to cast an enum element when assigning it to a same enum variable type in C?
I was having problems with this code for failing the MISRA C 2012 rule 10.3 that states:
The value of an expression shall not be assigned to an object with a narrower essential type or of a different essential type category
The code is this:
typedef enum
{
FLS_PROG_SUCCESS,
FLS_PROG_FAIL,
FLS_ERASE_SUCCESS2U,
FLS_ERASE_FAIL,
FLS_READ_SUCCESS,
FLS_READ_FAIL,
FLS_FORMAT_SUCCESS,
FLS_FORMAT_FAIL
}FLS_JobResult_t;
void Foo(void)
{
FLS_JobResult_t ProgramStatus;
/* Then I try to initialize the variable value */
ProgramStatus = FLS_PROG_SUCCESS;
...
}
And I accepted an answer that suggest that the tool may be flawed. I still do believe that but fooling around trying to fix that I put a name to the typedef enum declaration which now is:
typedef enum FLS_JobResult_tag
{
FLS_PROG_SUCCESS,
FLS_PROG_FAIL,
FLS_ERASE_SUCCESS2U,
FLS_ERASE_FAIL,
FLS_READ_SUCCESS,
FLS_READ_FAIL,
FLS_FORMAT_SUCCESS,
FLS_FORMAT_FAIL
}FLS_JobResult_t;
And as far as I know both are exactly the same. But then, surprise! The error went away! The rules checker is no longer flagging that as an error!!
Then doing some research I found this two questions:
What are the differences between these two typedef styles in C?
and
What's the difference between these two enum declarations - C?
And I realized that there are subtle differences between an anonymous enum and a named enum. But nothing that makes clear what could be the reason for the rule checker to complaint about one form of the other.
So the question is: What is the difference from an anonymous enum vs named enum that may break rule 10.3 from MISRA c 2012?
Both examples are compliant, and both for the same reasons: they are not assigning an object of a different essential type.
Let's clear up the confusion.
C grants developers/compilers a lot of freedom in its type system, but it also can lead to unintended results, with the potential for loss of value, sign or precision. MISRA-C:2012 helps enforce safer typing with its essential type model, which provides the rational basis for its rule definitions in controlling the use of type conversions and promoting awareness of implementation specific behavior (the 10.x Rules).
The essential type model replaces the MISRA-C:2004 standard’s “underlying type” model (which caused a lot of programmer grief enforcing unnecessary casts for one reason).
I suspect your tool is confused, and/or partially stuck with the older model.
The essential type rules that pertain to enumerations recognizes two different programming uses:
The C standard does not give a way of distinguishing between these uses. Therefore MISRA-C:2012 added the following distinct essential types of enumeration (while not affecting C behavior):
An example of an anonymous enum type:
enum {D = 10, E = 20, F = 30};
Both your examples are named enum types (and they are compliant because they are the same essential type). Other examples are:
enum JOHN {A, B, C};
enum PAUL {E, F, G} PAUL;
Thus, an example of a real 10.3 violation would be:
enum PAUL bar = B;
Reference: MISRA-C:2012 Appendix D.5 "The essential type of enumerations” amplifies this very well with other examples.