I recently stumbled on a glibc bug: https://sourceware.org/bugzilla/show_bug.cgi?id=13575
and note that cygwin has the same bug in 32 bit. test case 1: $ cat <<\EOF | gcc -E -P - | grep size_t #include <stdint.h> #include <sys/types.h> #include <limits.h> size_t a = SIZE_MAX; ssize_t b = SSIZE_MAX; EOF On 32-bit, we see that both types are based on int: typedef unsigned int size_t; typedef signed int _ssize_t; typedef _ssize_t ssize_t; but that the constant for SSIZE_MAX is based on long size_t a = (0xffffffffU); ssize_t b = (0x7fffffffL); On 64-bit, we see that both types are based on long, as are the constants: typedef long unsigned int size_t; typedef long signed int _ssize_t; typedef _ssize_t ssize_t; size_t a = (0xffffffffffffffffUL); ssize_t b = (0x7fffffffffffffffL); which is correct. test case 2: $ cat foo.c #include <stdio.h> #include <stdint.h> #include <sys/types.h> #include <limits.h> int main(void) { printf("%zu %zd\n", SIZE_MAX, SSIZE_MAX); return 0; } $ gcc -o foo -Wall -Wformat=2 foo.c Technically, there is NO portable way to pass ssize_t to printf without a cast (the standards do not guarantee that %zd is ssize_t, because ssize_t can be a different rank type than size_t) - but in practice, most platforms use the same rank for the two types (both glibc and Cygwin fall into this camp). Therefore, this should compile without warning; 64-bit is fine, but 32-bit gripes: foo.c: In function 'main': foo.c:6:10: warning: format '%zd' expects argument of type 'signed size_t', but argument 3 has type 'long int' [-Wformat=] Also, recall that both SIZE_MAX and SSIZE_MAX must be usable in #if expressions, so we can't use a cast to size_t in the macro, but instead have to expand directly to an expression with the right type. I'll probably try my hand at a patch later today. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature