Щоб розібратися, чому 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
ширшого, ніж 32-бітну ширину long
, але int
в більшості 64-бітних систем.
Це не могло бути long long int
, що все одно було додано пізніше, оскільки це було створено для ширини принаймні 64 біт навіть у 32-бітних системах.
Отже, потрібен був новий тип. Навіть якщо б це не було, всі ці інші типи означали щось інше, ніж зсув у масиві чи об’єкті. І якщо був би один урок з фіаско 32-до-64-бітової міграції, то слід було б конкретно визначити, які властивості потрібно мати типу, а не використовувати той, який означав різні речі в різних програмах.
int
якщоsome_size
він підписаний,size_t
якщо він не підписаний.