Чтобы понять, почему size_t
нужно существовать и как мы сюда попали:
С практической точки зрения, size_t
и ptrdiff_t
гарантированно будет иметь ширину 64 бита в 64-битной реализации, 32 бита в 32-битной реализации и так далее. Они не могли заставить любой существующий тип означать это на каждом компиляторе, не нарушая устаревший код.
А size_t
или ptrdiff_t
не обязательно совпадает с intptr_t
или uintptr_t
. Они отличались от определенных архитектур , которые до сих пор были в использовании , когда size_t
и ptrdiff_t
были добавлены к Стандарту в конце 80 - х годов, и становится устаревшим , когда C99 добавлено много новых типов , но еще не прошли (например, 16-разрядной Windows). Сервер x86 в 16-разрядном защищенном режиме имел сегментированную память, в которой максимальный размер массива или структуры мог составлять всего 65 536 байт, но far
указатель должен был иметь ширину 32 бита, шире регистров. На тех, intptr_t
было бы 32-битной шириной, но size_t
иptrdiff_t
может быть 16 бит в ширину и помещаться в регистр. И кто знал, какую операционную систему можно написать в будущем? Теоретически, архитектура i386 предлагает 32-битную модель сегментации с 48-битными указателями, которую никогда не использовала ни одна операционная система.
Тип смещения памяти не может быть, long
потому что слишком большой унаследованный код предполагает, что long
его ширина составляет ровно 32 бита. Это предположение было даже встроено в API-интерфейсы UNIX и Windows. К сожалению, во многих других устаревших кодах также предполагается, что a long
достаточно широк, чтобы содержать указатель, смещение файла, количество секунд, прошедших с 1970 года, и так далее. POSIX теперь предоставляет стандартизированный способ заставить последнее предположение быть верным вместо первого, но ни одно из них не является переносимым.
Этого не может быть, int
потому что лишь крошечная горстка компиляторов в 90-х имела int
ширину 64 бита. Тогда они действительно стали странными, держа long
32 бита в ширину. Следующая редакция Стандарта объявила его незаконным, поскольку int
он шире long
, но int
по-прежнему имеет ширину 32 бита в большинстве 64-битных систем.
Этого не может быть long long int
, что в любом случае было добавлено позже, поскольку он был создан, чтобы иметь ширину не менее 64 бит даже в 32-битных системах.
Итак, новый тип был необходим. Даже если это не так, все эти другие типы означают нечто иное, чем смещение в массиве или объекте. И если бы был один урок из фиаско 32-битной миграции, то нужно было конкретно указать, какие свойства должен иметь тип, и не использовать тот, который имел разные значения в разных программах.
int
ifsome_size
подписано,size_t
если оно не подписано.