Ответ 1
Невозможно вообще определить такой тип. Совершенно законно для реализации сделать size_t
самый большой поддерживаемый неподписанный тип, что означало бы, что ни один из подписанных типов не может содержать все его значения.
ptrdiff_t
не обязательно достаточно широка. Это результат вычитания двух указателей, но нет ничего, что говорит, что вычитание указателя не может переполняться. См. Раздел 5.7 стандарта С++:
Когда два указателя на элементы одного и того же объекта массива вычитаются, результатом является разность индексов двух массивов элементы. Тип результата - это подписанная реализация. интегральный тип; этот тип должен быть того же типа, который определяется как
std::ptrdiff_t
в заголовке<cstddef>
(18.2). Как и с любым другим арифметическое переполнение, если результат не помещается в предоставленное пространство, поведение undefined.
Самый большой подписанный тип - intmax_t
, определенный в <stdint.h>
или <cstdint>
. Это функция C99, а С++ 11 - первый стандарт С++, который включает стандартную библиотеку C99, поэтому ваш компилятор может ее не поддерживать (и, скорее всего, MSVC этого не делает). Если существует тип подписанного типа, достаточно широкий для хранения всех возможных значений типа size_t
, тогда intmax_t
(хотя может быть и более узкий тип подписанного типа, который также квалифицируется).
Вы также можете использовать long long
, который является подписанным типом, гарантированным как минимум 64 бита (и, скорее всего, такой же, как intmax_t
). Даже если он недостаточно широк для хранения всех возможных значений типа size_t
, он почти наверняка сохранит все соответствующие значения типа size_t
- если только ваша реализация не поддерживает объекты размером более 8 экзабайт (это 8192 петабайт или 8388608 терабайт).
(Примечание. Я использую двоичные определения "exa-", "peta-" и "tera-", которые имеют сомнительную достоверность.)