Search code examples
ccompiler-warningsgcc-warning

C -Wformat warning for integer promotion in printf


I am using GCC 5.2.1 with an ARM Cortex A9, and compiling with -std=c11 and -Wformat-signedness.

How do I avoid a -Wformat warning in this case?

int main()
{
    enum
    {
        A = 0,
        B
    };
    char buff[100];
    snprintf(buff, 100, "Value is 0x%04x\n", A);
    return 0;
}

This produces a warning:

format '%x' expects argument of type 'unsigned int', but argument 4 has
  type 'int' [-Werror=format=]
    snprintf(buff, 100, "Value is 0x%04x\n", A);
                        ^

An explicit cast gives the same result:

format '%x' expects argument of type 'unsigned int', but argument 4 has 
  type 'int' [-Werror=format=]
    snprintf(buff, 100, "Value is 0x%04x\n", (uint16_t)A);
                        ^

Solution

  • How do I avoid a -Wformat warning in this case?

    Cast the enumerated type to unsigned to match "%x".

    // snprintf(buff, 100, "Value is 0x%04x\n", A);
    snprintf(buff, 100, "Value is 0x%04x\n", (unsigned) A);
    

    o,u,x,X The unsigned int argument is converted to ... C11 §7.21.6.1 8


    If code casts to something other than unsigned, for some reason, use the specified matching print specifier. @Chrono Kitsune

    #include <inttypes.h> 
    
    // snprintf(buff, 100, "Value is 0x%04x\n", (uint16_t)A);
    snprintf(buff, 100, "Value is 0x%04" PRIX16 "\n", (uint16_t)A);
    

    Moral if the story: Use matching print specifiers with each argument.