Почему size_t, когда int будет достаточно для размера массива? - PullRequest
13 голосов
/ 14 мая 2011

Стандарт C гарантирует, что int способен хранить каждый возможный размер массива.По крайней мере, это то, что я понимаю из чтения §6.5.2.1, подраздел 1 (ограничения подписки на массив):

Одно из выражений должно иметь тип '' указатель на тип объекта '', другое выражениебудет иметь целочисленный тип, а результат будет иметь тип '' type ''.

Поскольку мы будем использовать int s в качестве индексов массива, почему мы должны использовать size_t для определения размерамассива?

Почему strlen() возвращает size_t, когда int будет достаточно?

Ответы [ 5 ]

25 голосов
/ 14 мая 2011

Термин «целочисленный тип» не означает int - например, char и short являются целочисленными типами.

Просто потому, что вы можете использовать int для подписимассив не обязательно означает, что он может охватить все возможные элементы массива.

Более конкретно о size_t против int, одним примером могут быть платформы, где int может быть 16-битным типом иsize_t может быть 32-разрядным типом (или более распространенным 32-разрядным int против 64-разрядным size_t различием на современных 64-разрядных платформах).

6 голосов
/ 15 мая 2011

целочисленный тип не обязательно является "int". "long long" также является целочисленным типом, как и "size_t".

Массивы могут быть больше 2 ГБ. Это свойство очень удобно для тех, кто пишет программы, требующие много памяти, например, СУБД с большими пулами буферов, серверы приложений с большими кэшами памяти и т. Д. Массивы размером более 2 ГБ / 4 ГБ - вот и весь смысл 64-битных вычислений:

size_t для strlen (), по крайней мере, звучит совместимо с тем, как стандарт C обрабатывает массивы, имеет ли это практический смысл или нет, или кто-то видел строки такого размера, это другой вопрос.

2 голосов
/ 15 мая 2011

Во-первых, то, что вы цитировали из стандарта, не содержит никаких ссылок на тип int конкретно.И нет, int не гарантированно будет достаточным для хранения размера любого объекта (включая массивы) в C.

Во-вторых, язык C на самом деле не имеет конкретно "подписок на массивы".Подписка на массив осуществляется через арифметику указателей.А интегральный операнд в арифметике указателей имеет тип ptrdiff_t.Не size_t, не int, а ptrdiff_t.Это тип со знаком, BTW, означающий, что значение может быть отрицательным.

В-третьих, цель size_t - сохранить размер любого объекта в программе (т. Е. Сохранить результат sizeof).Он не предназначен для немедленного использования в качестве индекса массива.Так получилось, что он работает как индекс массива, поскольку гарантируется, что он всегда достаточно велик, чтобы индексировать любой массив.Однако, с абстрактной точки зрения, «массив» - это особый вид «контейнера», и существуют другие виды контейнеров (основанные на списках, основанные на дереве и т. Д.).В общем случае size_t недостаточно для хранения размера любого контейнера, что в общем случае делает его сомнительным выбором и для индексации массива.(strlen, с другой стороны, это функция, которая работает именно с массивами, что делает size_t подходящим для этого.)

0 голосов
/ 06 мая 2016

Когда был написан стандарт C, для машин было характерно иметь 16-битный тип int и быть неспособным обрабатывать любой отдельный объект размером более 65535 байтов, но, тем не менее, может обрабатывать объекты размером более 32767 байтов. Поскольку арифметика без знака int будет достаточно большой, чтобы обрабатывать самые большие размер таких объектов, но арифметика со знаком int не будет, size_t был определен быть без знака, чтобы размещать такие объекты без необходимости использовать «длинный» вычисления.

На машинах, где максимально допустимый размер объекта находится между INT_MAX и UINT_MAX, разница между указателями на начало и конец такого объект может быть слишком большим, чтобы поместиться в "int". Пока Стандарт не навязывает любые требования к тому, как реализации должны справляться с этим, общий подход это определить поведение целочисленного типа и указателя обтекания так, что если S и E указатели на начало и конец символа [49152], тогда даже если E-S будет превышать INT_MAX, это даст значение, которое, при добавлении к S, будет доходность Е.

В настоящее время редко когда есть какое-либо реальное преимущество в том, что size_t является тип без знака (так как код, которому нужны объекты размером более 2 ГБ, часто нужно использовать 64-битные указатели по другим причинам), и это вызывает много видов Сравнения, включающие размеры объектов, ведут себя нелогично, но Тот факт, что sizeof выражений дает тип без знака, достаточно хорошо Укоренилось, что это вряд ли когда-либо изменится.

0 голосов
/ 14 мая 2011

size_t - это typedef целого числа без знака (например, int или long).

На некоторых 64-битных платформах int может быть 32-битным, а size_t может быть 64-битным.

Используется как более стандартный способ для размера.

...