I have a struct where I use bitfields to optimize memory. I have a uint64_t
type and I want to print its value. When compiled it shows me this warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 5 has type ‘long unsigned int:48’ [-Wformat=]
I have already tried to supress this warning by typing while compiling -Wno-format
. I'm wondering if there are a better way to do it.
Here some code:
#include <stdint.h>
#include <stdio.h>
typedef struct gn_addr
{
unsigned int m:1;
unsigned int st:5;
unsigned int reserved:10;
uint64_t mid:48;
} gn_addr ;
void gn_addr__print(gn_addr *self)
{
printf("M=>%d\nST=>%d\nReserved=>%d\nMID=>%lu\nTotal size %ld bytes\n",
self->m, self->st, self->reserved, self->mid, sizeof(self));
}
While you should definitely apply the fixes in the other answers to get portable format specifiers, the warning will persist. The reason is that extra arguments to a variadic function like printf
undergo argument promotions. Argument promotions include integer promotion.
The rules for integer promotions will convert any integer with a conversion rank less than int
/unsigned
, as well as bit-fields, into the an int
/unsigned
. So for your initial bit-fields, you get int
automatically.
For integers with a higher conversion rank than int
/unsigned
, no promotion occurs. So your bit-field is not promoted to an uint64_t
, and you get a warning about argument mismatch. You need a cast.
(uint64_t)self->mid
Btw, since nobody mentioned, the portable format specifier for a size_t
(the type of the sizeof
operator) is %zu
. You should use that instead of %ld
.