This article suggest being aware to not merge enums definitions into a principal enum as they usually need an inappropriate cast to be used.
To give an example of how this causes problems let’s suppose two functions to get the functionality for a specific entity called “joint”. These functions use three enum types, one called E_JOINT_FUNCTION which identifies the functions that a Wheel Joint type can perform; the other two enums are types for the Upper Joint and the Lower Joint available in the system:
These two functions return the functionality that is being used in the specific Upper Joint or Lower Joint.
In this example, we are going to use these functions to determine the functionality in the Joint that is reporting a failure. There might be different errors in the low level systems, and this low level system handles the index of the errors differently from the indexes of Upper Joint and Lower Joint, therefore we create a new type called E_ERR_JOINT_TYPE:
Next, we might have some requirements that tell us that we need to report in which part of the joint was the failure present, to do so, we created a new function called publishErrorLog():
static void publishErrorLog(E_ERR_JOINT_TYPE error);
This function requires the distinction between E_UPPER_JOINT and E_LOWER_JOINT as they will be processed differently in further process inside the function. Since there might be different constraints, we decided to maintain the logic of both type of joints on this function. Moreover, to get the feature of the specific joint feature we need to cast from E_ERR_JOINT_TYPE to either E_UPPER_JOINT or E_LOWER_JOINT. This approach yields to a problem because, both E_HSC_CHANNEL and E_LSC_CHANNEL have less elements than E_ERR_CHANNEL_TYPE, therefore it is possible to pass a value E_ERR_JOINT_TYPE that cannot be represented on E_UPPER_JOINT or E_LOWER_JOINT.
MISRA Rule 10.3 is related with this issue: Expression assigned to a narrower or different essential type is forbidden. This problem can be displayed in a thoughtless implementation of publishErrorLog():
One approach to remove the MISRA warning is to split E_ERR_JOINT_TYPE into two local arrays that return the specific UJ/LJ. Those arrays can be placed as parameters in the Get_UJ_to_feature() and Get_LJJ_to_feature() functions. Notice that the array elements that cannot have an association with the enum type is set with an invalid value, for example, from E_ERR_JOINT_TYPE enum, the UJ elements are the third, fourth, fifth and sixth element, therefore the other elements are set as E_ERR_MAX.
In this way, we had removed the MISRA warning of the previous example.
1. Evade MISRA Rule 10.3 warning by no casting to narrower types.
2. Don’t merge enum definition to avoid non-permitted casts.