Чтобы понять, почему size_t
нужно существовать и как мы сюда попали:
В практическом плане size_t
и ptrdiff_t
гарантированно будут иметь ширину 64 бита в 64-битной реализации, ширину 32 бита в 32-битной реализации и так далее. Они не могли заставить любой существующий тип означать это на каждом компиляторе, не нарушая устаревший код.
A 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. К сожалению, многие другие устаревшие коды также предполагали, что long
достаточно широк, чтобы содержать указатель, смещение файла, количество секунд, прошедших с 1970 года, и так далее. POSIX теперь предоставляет стандартизированный способ заставить последнее предположение быть верным вместо первого, но ни одно из них не является переносимым.
Это не может быть int
, потому что только крошечная горстка компиляторов в 90-х годах имела ширину int
64 бит. Тогда они действительно стали странными, держа ширину long
32 бита. В следующей редакции стандарта было объявлено, что int
шире, чем long
, незаконно, но в большинстве 64-битных систем int
по-прежнему имеет ширину 32 бита.
Это не может быть long long int
, который в любом случае был добавлен позже, поскольку он был создан, чтобы иметь ширину не менее 64 бит даже в 32-битных системах.
Итак, нужен новый тип. Даже если это не так, все эти другие типы означают нечто иное, чем смещение в массиве или объекте. И если бы был один урок из фиаско 32-битной миграции, то нужно было конкретно указать, какие свойства должен иметь тип, и не использовать тот, который имел разные значения в разных программах.