[tz] Compiler warning in tzcode2016g about SIZE_MAX being wider than int

Tom Lane tgl at sss.pgh.pa.us
Thu Oct 20 17:15:10 UTC 2016

When trying to build 2016g using macOS's current compiler (or, probably,
any reasonably late-model version of clang), I get

cc -DTZDIR=\"/usr/local/etc/zoneinfo\"    -c -o zic.o zic.c
zic.c:434:51: warning: implicit conversion from 'unsigned long long' to 'int' changes value from 18446744073709551615 to -1 [-Wconstant-conversion]
                int amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;
                    ~~~~                                        ^~~~~~~~
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/stdint.h:153:20: note: expanded from macro 'SIZE_MAX'
#define SIZE_MAX          UINT64_MAX
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/stdint.h:87:27: note: expanded from macro 'UINT64_MAX'
#define UINT64_MAX        18446744073709551615ULL
1 warning generated.

Or in other words, clang is pointing out, quite correctly, that SIZE_MAX
won't fit in an int.  This doesn't represent a runtime bug because the
condition "nitems_max < SIZE_MAX" can never fail, but that just begs
the question why have it.  I am not aware of any C implementation that
has ever had INT_MAX > SIZE_MAX, and surely there are none in use today.

I suggest, therefore, a fix along the lines of

$ diff -u zic.c~ zic.c
--- zic.c~      2016-09-06 00:39:50.000000000 -0400
+++ zic.c       2016-10-20 13:06:39.000000000 -0400
@@ -431,8 +431,7 @@
                return ptr;
        else {
                int nitems_max = INT_MAX - WORK_AROUND_QTBUG_53071;
-               int amax = nitems_max < SIZE_MAX ? nitems_max : SIZE_MAX;
-               if ((amax - 1) / 3 * 2 < *nitems_alloc)
+               if ((nitems_max - 1) / 3 * 2 < *nitems_alloc)
                        memory_exhausted(_("int overflow"));
                *nitems_alloc = *nitems_alloc + (*nitems_alloc >> 1) + 1;
                return erealloc(ptr, size_product(*nitems_alloc, itemsize));

Alternatively one might think of changing the types of nitems_max and
amax to size_t --- but that would just make it even more crystal clear
that the "nitems_max < SIZE_MAX" conditional is useless.  And if,
somewhere, one did find a C implementation in which size_t is narrower
than int, that coding wouldn't work at all.  Basically I don't see a
way of dealing with this that is superior to just assuming that INT_MAX
is less than or equal to SIZE_MAX.

			regards, tom lane

More information about the tz mailing list