cmisrapointer-conversion

MISRA C:2012 Rule 11.3 A cast shall not be performed between a pointer to object type and a pointer to a different object type


#define HNULL (void*)0
BYTE  *VRAM_OPTION_I_BIT = HNULL;
WORD  *VRAM_OPTION_I_WORD = HNULL;

void Func1(void)
{
    VRAM_OPTION_I_BIT     = (BYTE *)(PLC_Data + VRAM_OPTION_I_BIT_ADDR);
    VRAM_OPTION_I_WORD    = (WORD *)VRAM_OPTION_I_BIT; //  MISRA Violation 11.3
}

The above code gives a MISRA violation. MISRA C:2012 Rule 11.3 A cast shall not be performed between a pointer to object type and a pointer to a different object type

A common method that I found to solve it was to change the data type of VRAM_OPTION_I_WORD and VRAM_OPTION_I_BIT to void*.

However, the code gives compilation issues when run in the hardware. Is there a feasible method to solve it ?


Solution

  • The main concern here is that it isn't well-defined to access a byte array through a word pointer in C. Alignment and strict pointer aliasing being the reasons why, that's a FAQ and you can read about it here What is the strict aliasing rule?

    Now strict aliasing is mostly just an annoying "defect" in C when it comes to embedded systems and hard-ware related programming, but we can't ignore it, especially not in safety-related software. With a gcc-like compiler it is strongly recommended to disable all strict aliasing optimizations with -fno-strict-aliasing. That will remove the hazard but still not sate MISRA C and the code will not be portable either.

    Given that a byte in your setting corresponds to a character type, it is actually safe to access any data type through such a pointer, but that's a very special case and does not apply to larger object pointer types.

    Avoid using void* in high integrity embedded systems - there should ideally be no unknown types or type-generic programming in such a system. So it's not a solution but another problem.

    The general work-around is as follows:


    Unrelated to your question, common best practices in C are as follows: