madler / zlib

A massively spiffy yet delicately unobtrusive compression library.
http://zlib.net/
Other
5.55k stars 2.42k forks source link

fprintf warnings with "%lu" and a size_t value in infcover.c on a 32-bit build #930

Closed pmqs closed 6 months ago

pmqs commented 6 months ago

Seeing the same warning with gcc & clang on Ubuntu. clang helpfully suggests the fix to change the %lu into %zu

Not sure how far back into the past that %zu goes but both gcc & clang set to c89 mode build fine with %zu. Suspect that there may still be some compilers that will barf at %zu .

Other options are to cast the values to unsigned long or to use uLong for these values like in z_stream


This is what I see with gcc

$  CFLAGS="-m32" CC=gcc  ./configure && make infcover
...
gcc -m32 -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -I. -c -o infcover.o test/infcover.c
test/infcover.c: In function ‘mem_used’:
test/infcover.c:188:28: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘size_t’ {aka ‘unsigned int’} [-Wformat=]
  188 |     fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total);
      |                          ~~^                       ~~~~~~~~~~~
      |                            |                           |
      |                            long unsigned int           size_t {aka unsigned int}
      |                          %u
test/infcover.c: In function ‘mem_high’:
test/infcover.c:196:28: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘size_t’ {aka ‘unsigned int’} [-Wformat=]
  196 |     fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater);
      |                          ~~^                             ~~~~~~~~~~~~~~~
      |                            |                                 |
      |                            long unsigned int                 size_t {aka unsigned int}
      |                          %u
test/infcover.c: In function ‘mem_done’:
test/infcover.c:221:35: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 4 has type ‘size_t’ {aka ‘unsigned int’} [-Wformat=]
  221 |         fprintf(stderr, "** %s: %lu bytes in %d blocks not freed\n",
      |                                 ~~^
      |                                   |
      |                                   long unsigned int
      |                                 %u
  222 |                 prefix, zone->total, count);
      |                         ~~~~~~~~~~~
      |                             |
      |                             size_t {aka unsigned int}

This is with clang

clang -m32 -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN -I. -c -o infcover.o test/infcover.c
test/infcover.c:188:52: warning: format specifies type 'unsigned long' but the argument has type 'size_t' (aka 'unsigned int') [-Wformat]
    fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total);
                         ~~~                       ^~~~~~~~~~~
                         %zu
test/infcover.c:196:58: warning: format specifies type 'unsigned long' but the argument has type 'size_t' (aka 'unsigned int') [-Wformat]
    fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater);
                         ~~~                             ^~~~~~~~~~~~~~~
                         %zu
test/infcover.c:222:25: warning: format specifies type 'unsigned long' but the argument has type 'size_t' (aka 'unsigned int') [-Wformat]
                prefix, zone->total, count);
                        ^~~~~~~~~~~
3 warnings generated.
madler commented 6 months ago

C89/90 has no %zu or even long long. Given your observations, I will change them to %zu and hope for the best.

madler commented 6 months ago

https://github.com/madler/zlib/commit/81e7c386082ccff6a6f9ba78013a79cf8e1657d2