The core problem here has nothing to do with MISRA, but with attempting to store a value at a specific slot in a bit-field. You cannot know how your bit-field layout actually ends up in memory, because that's not defined in the C standard.
Is your bit-field allocating 8 value bits in the MS byte or LS byte? Is it taking endianess in accordance or is it not? What is the bit order? Nobody knows. Step 1 is to get rid of the bit-field.
Step 2 is to get rid of anything unsigned int
and use uint16_t
/uint32_t
.
As for MISRA-C 10.6 specifically, the rule against implicit conversion to a wider type was always rather misguided. The rationale MISRA used for this rule was to prevent people from writing code like uint32_t u32 = u16a + u16b;
and thinking that the u32
operand of =
somehow magically means that the operation will get carried out on 32 bits instead of 16. But on a 8/16 bit system, it is carried out with 16 bit arithmetic and there might be overflows/wrap-around.
Now as it happens, doing bit-shifts on signed types is always a very bad idea. pData[0]
gets implicitly promoted to int
which is signed. There are other MISRA rules dealing with this, rather than the one you quoted.
Regardless of MISRA, you should make a habit of always carrying out your shifts on unsigned types. "It's not dangerous in this case" is a bleak rationale. That means always write (uint32_t)pData[0] >> 5
and the cast should be applied before the shift not after it. This removes all uncertainties regarding undefined behavior left shifts and potentially arithmetic right shifts etc. Let the optimizer worry about the actual used size of the operands from there.