SSIZE_MAX bug on 32-bit

Eric Blake
Wed Jul 13 15:05:00 GMT 2016

I recently stumbled on a glibc bug:

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;

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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 604 bytes
Desc: OpenPGP digital signature
URL: <>

More information about the Cygwin mailing list