MISRA.CVALUE.IMPL.CASTThe value of an expression should not be implicitly converted to a different type. MISRA-C Rule 10.1 (required): The value of an expression of integer type shall not be implicitly converted to a different underlying type if:
MISRA-C Rule 10.2 (required): The value of an expression of floating type shall not be implicitly converted to a different type if:
Notice also that in describing integer conversions, the concern is always with underlying type rather than actual type. These two rules broadly encapsulate the following principles:
The intention when restricting implicit conversion of complex expressions is to require that in a sequence of arithmetic operations within an expression, all operations should be conducted in exactly the same arithmetic type. Notice that this does not imply that all operands in an expression are of the same type. The expression 'u32a + u16b + u16c' is compliant — both additions will notionally be performed in type U32. The expression 'u16a + u16b + u32c' is not compliant — the first addition is notionally performed in type U16 and the second in type U32. The word "notionally" is used because, in practice, the type in which arithmetic will be conducted will depend on the implemented size of an int. By observing the principle whereby all operations are performed in a consistent (underlying) type, it is possible to avoid programmer confusion and some of the dangers associated with integral promotion. Exampleextern void foo1(uint8_t x); int16_t t1(void) { ... foo1(u8a); /* compliant */ foo1(u8a + u8b); /* compliant */ foo1(s8a); /* not compliant */ foo1(u16a); /* not compliant */ foo1(2); /* not compliant */ foo1(2U); /* compliant */ foo1((uint8_t)2); /* compliant */ ... s8a + u8a /* not compliant */ ... s8a + (int8_t)u8a /* compliant */ s8b = u8a; /* not compliant */ ... u8a + 5 /* not compliant */ ... u8a + 5U /* compliant */ ... u8a + (uint8_t)5 /* compliant */ u8a = u16a; /* not compliant */ u8a = (uint8_t)u16a; /* compliant */ u8a = 5UL; /* not compliant */ ... u8a + 10UL /* compliant */ u8a = 5U; /* compliant */ ... u8a + 3 /* not compliant */ ... u8a >> 3 /* compliant */ ... u8a >> 3U /* compliant */ pca = "P"; /* compliant */ ... s32a + 80000 /* compliant */ ... s32a + 80000L /* compliant */ f32a = f64a; /* not compliant */ f32a = 2.5; /* not compliant - unsuffixed floating constants are of type double */ u8a = u8b + u8c; /* compliant */ s16a = u8b + u8b; /* not compliant */ s32a = u8b + u8c; /* not compliant */ f32a = 2.5F; /* compliant */ u8a = f32a; /* not compliant */ s32a = 1.0; /* not compliant */ s32a = u8b + u8c; /* not compliant */ f32a = 2.5F; /* compliant */ u8a = f32a; /* not compliant */ s32a = 1.0; /* not compliant */ f32a = 1; /* not compliant */ f32a = s16a; /* not compliant */ ... f32a + 1 /* not compliant */ ... f64a * s32a /* not compliant */ ... return (s32a); /* not compliant */ ... return (s16a); /* compliant */ ... return (20000); /* compliant */ ... return (20000L); /* not compliant */ ... return (s8a); /* not compliant */ ... return (u16a); /* not compliant */ } int16_t foo2(void) { ... ... (u16a + u16b) + u32a /* not compliant */ ... s32a + s8a + s8b /* compliant */ ... s8a + s8b + s32a /* not compliant */ f64a = f32a + f32b; /* not compliant */ f64a = f64b + f32a; /* compliant */ f64a = s32a / s32b; /* not compliant */ u32a = u16a + u16a; /* not compliant */ s16a = s8a; /* compliant */ s16a = s16b + 20000; /* compliant */ s32a = s16a + 20000; /* not compliant */ s32a = s16a + (int32_t)20000; /* compliant */ u16a = u16b + u8a; /* compliant */ foo1(u16a); /* not compliant */ foo1(u8a + u8b); /* compliant */ ... return s16a; /* compliant */ ... return s8a; /* not compliant */ } |