Search code examples
cbit-shiftklocwork

Understand Klocwork bitwise operation sign


When analysed by klocwork, the following line

pTxData[index] =  ( UINT8_C(0) << UINT8_C(4) );

gives error

Operand of bitwise operation has type 'signed char' instead of 'unsigned integer'

I already reduced the problem to the minimum by removing any #define and have absolutely no clue why this can happen.


Solution

  • For those unaware, UINT8_C is a C standard macro1) for getting an integer constant of type uint_least8_t rather than the default int.

    Thus UINT8_C(0) is equivalent to (uint_least8_t)0. This will be a small integer type. And as such it is subject to integer promotion2) when passed on as left operand to <<. After promotion it ends up as type int, equivalent to just writing 0.

    You should never use signed operands with bitwise operators, so this is the core reason for the error message. Corrected code should look like 0u << 4. Although this code is of course pointless for anything except self-documenting code. (And of course shifting the value 0 is always harmless.)

    Using UINT8_Con the right operand of << is nonsense - that operand does not partake in any type promotion of the result. If you need to use unsigned literals just to sate a coding standard, then use 4u. Notably, standards like MISRA-C do not require u suffix in cases where you actually don't need an unsigned type - this is a common source of false positives from tools.

    Summary - use this:

    pTxData[index] =  0u << 4;
    

    In addition, Klockwork is giving an incorrect diagnostic message. The operators in your expression are both likely equivalent to unsigned char and definitely not signed char like the tool says.


    1) Introduced in C99 7.18.4.1.

    2) See Implicit type promotion rules