Где найти определение size_t?
Я вижу переменные, определенные этим типом, но я не знаю, откуда он, и какова его цель. Почему бы не использовать int или unsigned int? (Как насчет других "похожих" типов? Void_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
, использование значимых типов имен помогает понять смысл и намерение вашей программы, как и любой богатый набор типов.