MISRA.ETYPE.ASSIGN.2012Assignment to an object of a narrower essential type or a different essential type category.
MISRA C 2012 Rule 10.3: The value of an expression shall not be assigned to an object with a narrower essential type or of a different essential type categoryC90 [Undefined 15; Implementation 16], C99 [Undefined 15, 16; Implementation 3.5(4)] Category: Required Analysis: Decidable, Single Translation Unit Applies to: C90, C99 AmplificationThe following operations are covered by this rule:
RationaleThe C language allows the programmer considerable freedom and will permit assignments between different arithmetic types to be performed automatically. However, the use of these implicit conversions can lead to unintended results, with the potential for loss of value, sign or precision. Further details of concerns with the C type system can be found in Appendix C. The use of stronger typing, as enforced by the MISRA essential type model, reduces the likelihood of these problems occurring. Exception
Exampleenum enuma { A1, A2, A3 } ena; enum enumb { B1, B2, B3 } enb; enum { K1=1, K2=128 }; The following are compliant: uint8_t u8a = 0; /* By exception */ bool_t flag = ( bool_t ) 0; bool_t set = true; /* true is essentially Boolean */ bool_t get = ( u8b > u8c ); ena = A1; s8a = K1; /* Constant value fits */ u8a = 2; /* By exception */ u8a = 2 * 24; /* By exception */ cha += 1; /* cha = cha + 1 assigns character to character */ pu8a = pu8b; /* Same essential type */ u8a = u8b + u8c + u8d; /* Same essential type */ u8a = ( uint8_t ) s8a; /* Cast gives same essential type */ u32a = u16a; /* Assignment to a wider essential type */ u32a = 2U + 125U; /* Assignment to a wider essential type */ use_uint16 ( u8a ); /* Assignment to a wider essential type */ use_uint16 ( u8a + u16b ); /* Assignment to same essential type */ The following are non-compliant as they have different essential type categories:
uint8_t u8a = 1.0f; /* unsigned and floating */ bool_t bla = 0; /* boolean and signed */ cha = 7; /* character and signed */ u8a = 'a'; /* unsigned and character */ u8b = 1 - 2; /* unsigned and signed */ u8c += 'a'; /* u8c = u8c + 'a' assigns character to unsigned */ use_uint32 ( s32a ); /* signed and unsigned */ The following are non-compliant as they contain assignments to a narrower essential type: s8a = K2; /* Constant value does not fit */ u16a = u32a; /* uint32_t to uint16_t */ use_uint16 ( u32a ); /* uint32_t to uint16_t */ uint8_t foo1 ( uint16_t x ) { return x; /* uint16_t to uint8_t */ } |