Search code examples
cprintftype-conversionformat-specifiersmisra

MISRA C 2004 10.1, signedness of printf "%x"


I'm getting errors from our static analysis tool about the following snippet:

uint8_t value = 24U;
char buffer[512];
int chars_printed = snprintf(buffer, sizeof(buffer),
                             "The value in hex is 0x%02hhX\r\n",
                             value);

The error is:

MISRA-2004 Rule 10.1 violation: implicitly converting a non-constant expression in a function argument. Converting "value", with underlying type "unsigned char" (8 bits, unsigned), to type "int" (32 bits, signed).

What is the signedness and bit-width that MISRA is expecting from a "%X" specifier?

The "%X" is said to take an unsigned int from the cppreference page.

There are no errors from the IAR Compiler's MISRA C 2004 checker.
This one is from Coverity.


Solution

  • The problem is that the printf family implicitly promotes all arguments of a small integer type to int. Implicit type promotions of that kind is not allowed by rule 10.1 and this is why you get a MISRA violation error. It has nothing to do with the format specifier.

    For MISRA-compliance, simply cast the value explicitly before passing it to the function: (uint32_t)value.

    Please also note that MISRA doesn't allowed you to use stdio.h in production code.