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).

Reply via email to