Does size_t have the same size and alignment as ptrdiff_t?

911 Views Asked by At

On my platform (and on most of them I think) std::size_t and std::ptrdiff_t have the same size and the same alignment. Is there any platform where that is not true? In short: is it required by the standard?

3

There are 3 best solutions below

5
On BEST ANSWER

In short: is it required by the standard?

No. The only requirement is from [support.types.layout]/2 and it is:

The type ptrdiff_­t is an implementation-defined signed integer type that can hold the difference of two subscripts in an array object, as described in [expr.add].

There is paragraph 4

[ Note: It is recommended that implementations choose types for ptrdiff_­t and size_­t whose integer conversion ranks are no greater than that of signed long int unless a larger size is necessary to contain all the possible values. — end note ]

but notes are non-normative and it is only a recommendation, not a requirement.


std::size_t is defined as

The type size_­t is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object ([expr.sizeof]).

in paragraph 3 and it also has no requirement that they be the same.

0
On

On my platform ... std::size_t and std::ptrdiff_t have the same size

How is this compliant?

C has (which I believe C++ inherits - if not let me know to delete) as UB in § J.2:

The result of subtracting two pointers is not representable in an object of type ptrdiff_t (6.5.6)."

This allows the type of ptrdiff_t to be the signed counterpart of the unsigned size_t.
When paired as such with no padding,

char a[PTRDIFF_MAX + (size_t)1];         // OK with enough memory in the location needed
size_t size_a = sizeof a;                // OK             
size_t diff0 = &a[sizeof a - 1] - &a[0]; // OK
ptrdiff_t diff1 = &a[sizeof a] - &a[0];  // UB
ptrdiff_t diff2 = %a[0] - &a[sizeof a];  // UB

Moral of the story: troubles with pointer subtraction (result type: ptrdiff_t) may begin when the array element count exceeds PTRDIFF_MAX.

3
On

It is not required by the standard.

Note that the current crop of Intel processors have 48 bit pointers under the hood.

So personally I don't see it too far-fetched to conceive a 64 bit unsigned for std::size_t and a 49 bit signed type for a std::ptrdiff_t. Although such a scheme would be a headache to implement.

More interestingly once chipsets evolve to have 64 bit pointers (we are some way off that being necessary), presumably std::ptrdiff_t will have to be at least 65 bits! Personally therefore I keep in mind that one day sizeof(std::ptrdiff_t) may be larger than sizeof(std::size_t).