Я вижу переменные, определенные этим типом, но я не знаю, откуда он, и какова его цель. Почему бы не использовать int или unsigned int? (Как насчет других "похожих" типов? Void_t и т.д.).
Где найти определение size_t?
Ответ 1
От Wikipedia
Заголовочные файлы
stdlib.h
иstddef.h
определяют тип данных под названиемsize_t
1, который используется для представления размера объекта, Функции библиотеки, которые принимают размеры, предполагают, что они имеют типsize_t
, а оператор sizeof оценивается какsize_t
.Фактический тип
size_t
зависит от платформы; распространенная ошибка заключается в том, чтобы предположить, чтоsize_t
совпадает с unsigned int, что может привести к ошибкам программирования, 2, в частности, как 64-битные архитектуры становятся более распространенными.
От C99 7.17.1/2
В стандартном заголовке
определены следующие типы и макросы:stddef.h
< надрез >
size_t
который является целым числом без знака результата оператора sizeof
Ответ 2
size_t
- это целочисленный тип без знака результата оператора sizeof (ISO C99, раздел 7.17.)
Оператор sizeof
дает размер (в байтах) своего операнда, который может быть
выражение или имя в скобках типа. Размер определяется по типу
операнд. Результат - целое число. Значение результата определяется реализацией и
его тип (целочисленный тип без знака) равен size_t
(ISO C99, раздел 6.5.3.4.)
Ответ 3
В соответствии с size_t description на 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>
Ответ 4
Практически говоря, size_t
представляет количество байтов, которые вы можете адресовать. На большинстве современных архитектур за последние 10-15 лет это было 32 бита, который также был размером беззнакового int. Однако мы переходим на 64-битную адресацию, а uint
, скорее всего, останется на 32 бита (размер не гарантируется в стандарте С++). Чтобы ваш код зависел от размера памяти, переносимого по архитектурам, вы должны использовать size_t
. Например, такие вещи, как размеры массива, всегда должны использовать size_t
. Если вы посмотрите на стандартные контейнеры, ::size()
всегда возвращает size_t
.
Также обратите внимание, что в visual studio есть опция компиляции, которая может проверять эти типы ошибок под названием "Обнаружение 64-разрядных проблем переносимости".
Ответ 5
Таким образом, вы всегда знаете, что такое размер, потому что определенный тип предназначен для размеров. Сам вопрос показывает, что это может быть проблемой: это int
или unsigned int
? Кроме того, какова величина (short
, int
, long
и т.д.)?
Поскольку назначается определенный тип, вам не нужно беспокоиться о длине или подписанности.
Фактическое определение можно найти в С++ Reference Library, в котором говорится:
Тип:
size_t
(Неподписанный тип интеграла)Заголовок:
<cstring>
size_t
соответствует целочисленному типу данных, возвращаемому оператором языкаsizeof
и определяется в заголовочном файле<cstring>
(среди прочих) как неподписанный тип интеграла.В
<cstring>
он используется как тип параметраnum
в функцияхmemchr
,memcmp
,memcpy
,memmove
,memset
,strncat
,strncmp
,strncpy
иstrxfrm
, который во всех случаях используется для указания максимального количества байтов или символов, на которые должна влиять функция.Он также используется как возвращаемый тип для
strcspn
,strlen
,strspn
иstrxfrm
для возврата размеров и длины.
Ответ 6
size_t должен быть определен в ваших стандартных заголовках библиотеки. По моему опыту, обычно это просто typedef для unsigned int. Дело в том, что это не обязательно. Такие типы, как size_t, позволяют стандартным разработчикам библиотеки свободно изменять свои базовые типы данных, если это необходимо для платформы. Если вы предполагаете, что size_t всегда является unsigned int (через кастинг и т.д.), Вы можете столкнуться с проблемами в будущем, если ваш поставщик изменяет size_t, например. 64-битный тип. По этой причине опасно предполагать что-либо об этом или любом другом типе библиотеки.
Ответ 7
Я не знаком с void_t
, кроме как в результате поиска Google (он использовался в a vmalloc
библиотеке от Kiem-Phong Vo в AT & T Research - я уверен, что он использовался и в других библиотеках).
Различные xxx_t typedefs используются для абстрагирования типа из определенной определенной реализации, поскольку конкретные типы, используемые для определенных вещей, могут отличаться от одной платформы к другой. Например:
- size_t абстрагирует тип, используемый для хранения размера объектов, потому что на некоторых системах это будет 32-битное значение, а на других может быть 16-разрядное или 64-разрядное.
-
void_t
абстрагирует тип указателя, возвращаемого библиотечными подпрограммамиvmalloc
, потому что он был написан для работы с системами, которые предписывают ANSI/ISO C, где ключевое словоvoid
может не существовать. По крайней мере, это то, что я думаю. -
wchar_t
абстрагирует тип, используемый для широких символов, поскольку на некоторых системах он будет 16-разрядным типом, а для других он будет 32-разрядным.
Итак, если вы пишете свой код обработки большого символа, чтобы использовать тип wchar_t
вместо, скажем unsigned short
, этот код предположительно будет более переносимым на различные платформы.
Ответ 8
В минималистических программах, где определение size_t
не было "случайно" в некоторых, но я все еще нуждаюсь в нем в некотором контексте (например, для доступа к std::vector<double>
), то я использую этот контекст для извлечения правильного типа, Например typedef std::vector<double>::size_type size_t
.
(Окружать с помощью namespace {...}
, если необходимо, чтобы ограничить область действия.)
Ответ 9
Что касается "Почему бы не использовать int или unsigned int?", просто потому, что он семантически более значим не для. Существует практическая причина, что это может быть, скажем, typedef
d как int
, а затем обновлено до long
позже, без необходимости изменять свой код, конечно, но более фундаментально, чем предполагается тип быть значимым. Чтобы значительно упростить, переменная типа size_t
подходит и используется для, содержащих размеры вещей, точно так же, как time_t
подходит для хранения значений времени. То, как они на самом деле реализованы, должно быть вполне корректным. По сравнению с тем, что вы вызываете все int
, использование значимых типов имен помогает понять смысл и намерение вашей программы, как и любой богатый набор типов.