Де знайти визначення size_t?


123

Я бачу змінні, визначені для цього типу, але я не знаю, звідки він походить, а також яке його призначення. Чому б не використовувати int або unsigned int? (Як щодо інших "подібних" типів? Void_t тощо).



@kjfletch: hhhmmm, дивно, що пошук терміна "size_t" (як я це робив раніше) не відповів на це питання.
Елізео Окампос

1
@Eliseo - Функція пошуку Stackoverflow жахлива. Використовуйте Google замість параметра "site: stackoverflow.com" замість цього.
Майкл Берр

8
ОП спеціально запитав Де я можу визначити розмір size_t? Я приземлився тут, шукаючи те саме. Цитується дубль не обговорює, де знайти декларацію.
jww

9
Це питання, очевидно, не те саме питання, що пов'язане. "Де я щось можу знайти" - це не те саме, що "Яка різниця між" (навіть якщо відповідь на один дає відповідь іншому). Мій пошук в Google за "c ++, де є визначенням розміру" взяв мене прямо тут, і я б пропустив інше питання, тому що це інше .
Дан Ніссенбаум

Відповіді:


122

З Вікіпедії

stdlib.hІ stddef.hзаголовки визначають тип даних з ім'ям size_t1 , який використовується для позначення розміру об'єкта. Функції бібліотеки, які приймають розміри, очікують, що вони будуть size_tтиповими, і розмір оператора оцінює size_t.

Фактичний тип size_tплатформи залежить; загальна помилка полягає в тому, щоб вважати , size_tтакими ж , як беззнаковий Int, що може привести до помилок програмування, 2 в зокрема , в вигляді 64-розрядні архітектури стають все більш поширеною.

Від C99 7.17.1 / 2

Наступні типи та макроси визначені у стандартному заголовку stddef.h

<snip>

size_t

який є непідписаним цілим типом результату оператора sizeof оператора


2
Наприклад, на Win64, intа unsigned intтипи - 32 біти, тоді як size_t - 64 біт.
Майкл Берр

7
Будь ласка, зверніться до стандарту ISO C (99) (з якого включає стандарт C ++) розділи 7.17 та 7.18.3
Мартін Йорк

3
@LokiAstari, чому ти просто не відредагуєш відповідь, оскільки ти знаєш, де це написано у стандарті?
Привіт-Ангел

То де ж відповідь С ++?
Лотар

@Lothar Я думаю, що різниця лише в тому, що size_t може бути ключовим словом, інакше має те саме значення.
Пол Стеліан

30

Відповідно до опису size_t на сайті en.cppreference.com size_t визначено у наступних заголовках:

std::size_t

...    

Defined in header <cstddef>         
Defined in header <cstdio>      
Defined in header <cstring>         
Defined in header <ctime>       
Defined in header <cwchar>

2
Це саме те, що мені було потрібно, цю відповідь слід підтримати.
neodelphi

27

size_t - це цілочислений неподписаний результат результату оператора sizeof (ISO C99, Розділ 7.17.)

sizeofОператор дає розмір (в байтах) свого операнда, який може бути вираз в дужках або ім'я типу. Розмір визначається від типу операнду. Результат - ціле число. Значення результату визначено реалізацією, а його тип (непідписаний цілочисельний тип) size_t(ISO C99, розділ 6.5.3.4.)


Найкраща відповідь, як це цитує стандарт.
Мартін Йорк

1
@Martin - досить правда, але я вважаю, що частина питання "чому не підписаний int used" є такою ж цікавою (або більше), як і частина "what is size_t", і цього ви не знайдете в стандарті .
Майкл Берр

Так, за винятком "Розділу 17.17 ": стор. Це рідко, ніхто не сказав ні слова про Void_t
Eliseo Ocampos

Я приймаю цю відповідь, оскільки вона відповідає безпосередньо на питання, але було б чудово, якби вона відповіла відповіді Майкла.
Eliseo Ocampos

58
Шкода, що відповідь не підкаже, який файл заголовка включати.
Метт

6

Практично кажучи, size_tце кількість байтів, на які можна звернутися. У більшості сучасних архітектур за останні 10-15 років було 32 біти, що також було розміром неподписаного int. Однак ми переходимо до 64-бітової адреси, в той час як uint, швидше за все, розміщення буде на 32 бітах (розмір не гарантується в стандарті c ++). Щоб зробити свій код, який залежить від розміру пам'яті, переносним для всіх архітектур, ви повинні використовувати size_t. Наприклад, такі речі, як розміри масиву, завжди повинні використовувати size_ts. Якщо ви подивитеся на стандартні контейнери, ::size()завжди повертається a size_t.

Також зауважте, у візуальної студії є можливість компіляції, яка може перевірити наявність цих помилок під назвою "Виявити проблеми з 64-розрядною портативністю".


2

Таким чином, ви завжди знаєте, що таке розмір, адже конкретний тип присвячений розмірам. Саме власне запитання показує, що це може бути проблемою: це intчи це unsigned int? Крім того , що величина ( short, int, longі т.д.)?

Оскільки призначено певний тип, вам не доведеться турбуватися про довжину чи підпис.

Дійсне визначення можна знайти в довідковій бібліотеці C ++ , де сказано:

Тип: size_t(Непідписаний інтегральний тип)

Заголовок: <cstring>

size_tвідповідає інтегральному типу даних, що повертається оператором мови sizeofі визначається у <cstring>файлі заголовка (серед інших) як непідписаний інтегральний тип.

В <cstring>, він використовується як тип параметра numу функції memchr, memcmp, memcpy, memmove, memset, strncat, strncmp, strncpyі strxfrm, що у всіх випадках використовується , щоб вказати максимальну кількість байтів або символів , функція повинна впливати.

Він також використовується в якості повертається типу для strcspn, strlen, strspnі strxfrmдо розмірів повернення і довжини.


2

size_t має бути визначено у заголовках вашої стандартної бібліотеки. На мій досвід, це, як правило, просто typedef для непідписаного int. Сенс у тому, що цього не повинно бути. Такі типи, як size_t, дозволяють звичайному постачальнику бібліотеки змінювати свої базові типи даних, якщо це підходить для платформи. Якщо ви вважаєте, що size_t завжди не підписаний int (через кастинг тощо), у майбутньому ви можете зіткнутися з проблемами, якщо ваш постачальник змінить size_t на 64-бітний тип. З цієї причини небезпечно припускати щось про цей чи будь-який інший тип бібліотеки.


1

Я не знайомий з , void_tкрім як в результаті пошуку Google (він використовується в вигляді vmallocбібліотеки по Кию-Фонг Vo в AT & T Research - Я впевнений , що він використовується в інших бібліотеках, а).

Різні типи xxx_t використовуються для абстрагування типу з певної певної реалізації, оскільки конкретні типи, які використовуються для певних речей, можуть відрізнятися від однієї платформи до іншої. Наприклад:

  • size_t абстрагує тип, який використовується для розміщення об'єктів, оскільки в деяких системах це буде 32-бітове значення, в інших це може бути 16-бітне або 64-бітове.
  • Void_tабстрагує тип покажчика, який повертається vmallocпідпрограми бібліотеки, оскільки він був написаний для роботи в системах, які датували ANSI / ISO C, де voidключове слово може не існувати. Принаймні, це я здогадуюсь.
  • wchar_t абстрагує тип, що використовується для широких символів, оскільки в деяких системах це буде 16-ти бітний тип, в інших - 32-бітний тип.

Тож якщо ви пишете свій широкий код обробки символів для використання wchar_tтипу замість, скажімо unsigned short, цей код, ймовірно, буде більш портативним для різних платформ.


Це частково я шукав. Як я вже говорив у коментарі у відповіді fpmurphy, було б чудово, що його можна доповнити цією відповіддю (Якщо ви не заперечуєте, можливо, ви зможете її відредагувати) :)
Eliseo Ocampos

1

У мінімалістичних програмах, де size_tвизначення не завантажувалося "випадково", у деяких включаються, але мені все одно це потрібно в якомусь контексті (наприклад, для доступу std::vector<double>), тоді я використовую цей контекст для отримання потрібного типу. Наприклад typedef std::vector<double>::size_type size_t.

(При namespace {...}необхідності оточуйте їх, щоб обмежити область застосування.)


1

Що стосується "Чому б не використовувати int або unsigned int?", Просто тому, що це семантично значуще не робити. Існує практична причина того, що воно може бути, скажімо, typedefd як intі потім оновлене до більш longпізнього, без будь-кого, звичайно, змінювати свій код, але більш принципово, ніж цей тип повинен мати значення. Щоб значно спростити, змінна типу size_tпідходить і використовується для, що містить розміри речей, так само, як time_tце підходить для вмісту значень часу. Те, як вони реально реалізуються, має бути належним чином завданням впровадження. У порівнянні з тим, що просто називати все int, використання значущих імен шрифтів, як це допомагає з’ясувати значення та намір вашої програми, як і будь-який багатий набір типів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.