Ben Pfaff wrote:
On Sat, Dec 29, 2018 at 09:22:17AM -0800, Paul Eggert wrote:
(Using ptrdiff_t is part of my campaign to prefer ptrdiff_t to size_t. While
we're at it, let's change the other size_t args to ptrdiff_t, but I

Have you said anything about this campaign elsewhere?  I'd like to hear

I probably have, but it's easier for me to say something new afresh.

The C standard says that objects with size greater than PTRDIFF_MAX can cause trouble, because subtracting pointers into these objects yields undefined behavior if the resulting integer does not fit into ptrdiff_t. Worse, on many popular systems (including GNU), even if (P - Q)'s value fits into ptrdiff_t, (P - Q) can be calculated incorrectly if ((char *) P - (char *) Q) does not fit into ptrdiff_t; although this behavior is contrary to the C standard it's such a common problem that we cannot ignore it in portable code.

Because of this, C code should never allocate objects with size greater than PTRDIFF_MAX unless it never does pointer subtraction with the result, and it's generally simpler and more reliable if C code simply refuses to allocate such objects under any circumstances. Gnulib started doing this a couple of years ago with commit f3b846699de69b8e6a508396f7f778eb1e917a47, which causes xalloc-oversized and related modules to reject attempts to create objects larger than PTRDIFF_MAX bytes; this means many GNU applications are already safer. (Emacs has a different way of enforcing the same restriction internally.) Also, we are thinking of doing something similar with glibc's malloc/etc. functions in the next glibc version, though this patch has not gone in yet and may have to wait until the version after next.

As a result, C programs can now use either size_t or ptrdiff_t to store object sizes, since no actual object can have more than min (SIZE_MAX, PTRDIFF_MAX) bytes. Using signed types is better nowadays than using unsigned types, since many platforms now check for signed integer overflow and this can catch many bugs, some of them security-relevant, whereas unsigned arithmetic is well defined to wrap around with no overflow check (something that can be quite dangerous when doing size calculations). So, for reliability and security reasons, C programs should now prefer ptrdiff_t to size_t when dealing with object sizes.

Reply via email to