Search code examples
cmisra

Misra violation with bitwise operator


I have written the following piece of code which MISRA does not like:

UartPtr->C &= ((uint8_t)(~SIO_C2_SBK));

with

#define SIO_C2_SBK ((uint8_t)0x01u)

and UartPtr is defined as

UartPtr = (UartStruct*) 0x12345678; /* I know that this is also a violation of MISRA */

with the underlying datastructure:

typedef volatile struct UartStructTag
{
  uint8_t      BDH;
  uint8_t      BDL;
  uint8_t      C1;
  uint8_t      C2;
} UartStruct;

My Misra checker complains about the first line and states, that

An integer constant expression with negative value is being converted to an unsigned type.

However, the following line does not yield into a problem with MISRA:

UartPtr->C |= ((uint8_t)(SIO_C2_SBK));

So the problem comes from the bitwise negation. But as all operations are directly casted to uint8_t, i do not get the violation of the MISRA standard. Who wants to help me here?


Solution

  • In any arithmetic expression, values of types smaller than int are implicitly converted to int before they are processed. The C language cannot do arithmetic on types smaller than int. Thus, your code actually behaves like this:

    UartPtr->C &= ((uint8_t)(~(int)(uint8_t)0x01u));
    

    which is just

    UartPtr->C &= ((uint8_t)(~1));
    

    where ~1 has the value -2 on two's complement architectures.

    To fix this issue, convert to unsigned or any other unsigned type larger than int before applying bitwise not:

    UartPtr->C &= ((uint8_t)(~(unsigned)SIO_C2_SBK));