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?
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?
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.
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).
On my platform ...
std::size_tandstd::ptrdiff_thave 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.