typedef для подписанного типа, который может содержать size_t?

Существует ли стандартный (или собственный MSVC) typedef для подписанного типа, который может содержать полный диапазон size_t ценности? То есть в 64-битной системе это будет 128-битное целое число со знаком.

15

Решение

В целом невозможно определить такой тип. Это вполне законно для реализации, чтобы сделать size_t самый большой поддерживаемый тип без знака, что означает, что ни один тип со знаком не может содержать все его значения.

ptrdiff_t не обязательно достаточно широк. Это результат вычитания двух указателей, но ничто не говорит о том, что вычитание указателя не может быть переполнено. Смотрите раздел 5.7 стандарта C ++:

Когда два указателя на элементы одного и того же объекта массива вычитаются,
В результате разница индексов двух массивов
элементы. Тип результата — это подпись, определяемая реализацией.
интегральный тип; этот тип должен быть того же типа, который определен как
std::ptrdiff_t в <cstddef> заголовок (18.2). Как и с любым другим
арифметическое переполнение, если результат не помещается в предоставленное пространство,
поведение не определено.

Самый большой подписанный тип intmax_t, определенный в <stdint.h> или же <cstdint>, Это функция C99, и C ++ 11 был первым стандартом C ++, включившим стандартную библиотеку C99, поэтому ваш компилятор может не поддерживать ее (а MSVC, скорее всего, нет). Если тип со знаком достаточно широк, чтобы вместить все возможные значения типа size_t, затем intmax_t есть (хотя есть может быть быть более узким типом со знаком, который также квалифицируется).

Вы также можете использовать long longтип со знаком гарантированно должен быть не менее 64 бит (и, скорее всего, такой же, как intmax_t). Даже если он недостаточно широк, чтобы вместить все возможные значения типа size_tпочти наверняка Соответствующий значения типа size_t — если ваша реализация на самом деле не поддерживает объекты размером более 8 эксабайт (это 8192 петабайта или 8388608 терабайт).

(Обратите внимание, я использую двоичные определения «exa-», «peta-» и «tera-», которые имеют сомнительную обоснованность.)

11

Другие решения

Я предполагаю, что вам нужен этот тип для некоторой арифметики указателей. Маловероятно, что вам нужно что-то еще, кроме std::ptrdiff_t, Единственный случай, когда это будет играть роль на современном компьютере, — это когда вы работаете в 32-битном режиме и работаете с набором данных с более чем 2 ^ 31 байтами. (Это даже невозможно в Windows без специальной работы.) Вы не сможете использовать два массива такого размера одновременно. В этом случае вам, вероятно, все равно придется работать в 64-битном режиме.

В 64-битном режиме это, скорее всего, не будет проблемой в течение следующих 40 лет или около того с текущей скоростью разработки памяти. И когда это становится проблемой, скомпилируйте ваш код в 128-битном режиме, и он продолжит работать. 😉

2

Если вы хотите стандартный тип, который может содержать максимальное значение системы, возможно, <cstdint> (начиная с C ++ 11) может помочь.

В этом заголовке есть typedef, который содержит максимальный целочисленный тип ширины, тип intmax_t, intmax_t для целых чисел со знаком и uintmax_t для беззнаковых наибольшее целое число полностью поддерживается архитектурой.

Итак, предположим, что вы находитесь в 64-битной архитектуре, следующая инструкция:

std::cout << "intmax_t is same int64_t? "<< (std::is_same<intmax_t, int64_t>::value ? "Yes" : "No");

Будет выводить:

intmax_t это же int64_t? да

Живая демо.

Надеюсь, поможет.

2
По вопросам рекламы [email protected]