develooper Front page | perl.perl5.porters | Postings from August 2018

Re: RFC: Use ptrdiff_t instead of SSize_t

Thread Previous | Thread Next
From:
Tomasz Konojacki
Date:
August 3, 2018 22:48
Subject:
Re: RFC: Use ptrdiff_t instead of SSize_t
Message ID:
20180804004819.4089.5C4F47F8@xenu.pl

On Tue, 17 Jul 2018 14:29:49 +1000
Tony Cook <tony@develop-help.com> wrote:

> On Mon, Jul 16, 2018 at 06:12:25PM -0600, Karl Williamson wrote:
> > I stumbled upon this detail in stack overflow:
> > 
> > "The Open Group Base Specifications Issue 7, IEEE Std 1003.1, 2013 Edition,
> > description of <sys/types.h> says:
> > 
> > The type ssize_t is capable of storing values at least in the range [-1,
> > SSIZE_MAX]."
> > 
> > https://stackoverflow.com/questions/8649018/what-is-the-difference-between-ssize-t-and-ptrdiff-t
> > 
> > That means it doesn't necessarily work for the difference between two ptrs,
> > which is something I have used it for.
> > 
> > But ptrdiff_t must be capable of storing any such difference.  Also, any
> > object's size can be expressed as the difference between its ending and
> > starting pointers, so ptrdiff_t must be able to store anything ssize_t,
> > STRLEN or plain size_t can store, as well.
> 
> Not exactly, ptrdiff_t is signed while STRLEN and size_t are unsigned.
> 
> The obvious difference that STRLEN/size_t can store larger positive
> numbers than ptrdiff_t, but the more subtle difference is that
> overflow for unsigned integer types is well defined, while it causes
> undefined behaviour for signed integer types.
> 
> Tony

C11 says:

> When two pointers are subtracted, both shall point to elements of the same array object,
> or one past the last element of the array object; the result is the difference of the
> subscripts of the two array elements. The size of the result is implementation-defined,
> and its type (a signed integer type) is ptrdiff_t defined in the <stddef.h> header.
> If the result is not representable in an object of that type, the behavior is undefined.

There are many ways to interpret this passage, but according to (most?)
C compilers developers, it means that no object can be larger than
PTRDIFF_MAX. For example, gcc's optimizer assummes that strlen() will
never return anything larger than PTRDIFF_MAX [1].

There's also a blogpost[2] on this topic, which IMO is a very
interesting read.

If gcc and clang can assume that all objects won't be larger than
PTRDIFF_MAX, so can we. Also, in practice, ssize_t and ptrdiff_t on most
(all?) platforms are defined as exactly the same type.

BTW, the fact that compilers assume that objects can't be larger than
PTRDIFF_MAX has very dangerous implications on 32-bit platforms. Is it
possible to create string longer than PTRDIFF_MAX on 32-bit perls?. It
shouldn't be allowed.

[1] - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78153
[2] - https://trust-in-soft.com/objects-larger-than-ptrdiff_max-bytes/

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About