Is there a standard (or MSVC proprietary) typedef for a signed type that can contain the full range of size_t
values? I.e. on a 64-bit system, it would be a 128-bit signed integer.
It's not possible in general to define such a type. It's perfectly legal for an implementation to make size_t
the largest supported unsigned type, which would (almost certainly) mean that no signed type can hold all its values.
ptrdiff_t
is not necessarily wide enough. It's the result of subtracting two pointers, but there's nothing that says a pointer subtraction cannot overflow. See section 5.7 of the C++ standard:
When two pointers to elements of the same array object are subtracted, the result is the difference of the subscripts of the two array elements. The type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined as
std::ptrdiff_t
in the<cstddef>
header (18.2). As with any other arithmetic overflow, if the result does not fit in the space provided, the behavior is undefined.
The largest signed type is intmax_t
, defined in <stdint.h>
or <cstdint>
. That's a C99 feature, and C++11 was the first C++ standard to incorporate the C99 standard library, so your compiler might not support it (and MSVC most likely doesn't). If there's a signed type wide enough to hold all possible values of type size_t
, then intmax_t
is (though there might be a narrower signed type that also qualifies).
You can also use long long
, which is a signed type guaranteed to be at least 64 bits (and most likely the same as intmax_t
). Even if it's not wide enough to hold all possible values of type size_t
, it will almost certainly hold all relevant values of type size_t
-- unless your implementation actually supports objects bigger than 8 exabytes (that's 8192 petabytes, or 8388608 terabytes).
(Note, I'm using the binary definitions of "exa-", "peta-", and "tera-", which are of questionable validity.)