https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109516
Bug ID: 109516 Summary: warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'const long unsigned int:48' [-Wformat=] Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: yann at droneaud dot fr Target Milestone: --- I've discovered today an unexpected format related warning when asking to print a bitfield over unsigned long: $ cat > fmt-bitfield.c <<EOF #include <inttypes.h> #include <stdint.h> #include <stdio.h> struct struct24 { uint32_t uint24:24; }; void print24(const struct struct24 *s) { printf("%" PRIx32 "\n", s->uint24); } struct struct48 { uint64_t uint48:48; }; void print48(const struct struct48 *s) { printf("%" PRIx64 "\n", s->uint48); } EOF $ gcc -Wformat -c fmt-bitfield.c fmt-bitfield.c: In function 'print48': fmt-bitfield.c:13:10: warning: format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'long unsigned int:48' [-Wformat=] 13 | { printf("%" PRIx64 "\n", s->uint48); } | ^~~ ~~~~~~~~~ | | | long unsigned int:48 In file included from fmt-bitfield.c:1: /usr/include/inttypes.h:121:41: note: format string is defined here 121 | # define PRIx64 __PRI64_PREFIX "x" See https://godbolt.org/z/r44e5rfnh I understood that, according to C standard, bitfield over type other that int or bool is an implementation defined behavior. But GCC is expected to support bitfield over long as well: https://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit-fields-implementation.html - Allowable bit-field types other than _Bool, signed int, and unsigned int (C99 and C11 6.7.2.1). Other integer types, such as long int, and enumerated types are permitted even in strictly conforming mode. So I believe the warning is spurious, and formatting a value whose type is a bitfield over long should not trigger the warning when using %l format modifier. (For the record, clang doesn't report such warning).