Я вижу переменные, определенные этим типом, но не знаю, откуда они взялись и каково их назначение. Почему бы не использовать int или unsigned int? (А как насчет других «похожих» типов? Void_t и т. Д.).
@kjfletch: хххммм, странно, что поиск по запросу 'size_t' (как я делал ранее) не вернул этот вопрос.
Eliseo Ocampos,
1
@Eliseo - функция поиска Stackoverflow ужасна. Вместо этого используйте Google с параметром site: stackoverflow.com.
Michael Burr
8
ОП специально спросил, где мне найти определение size_t? Я приземлился здесь, ища то же самое. В цитируемом дубликате не обсуждается, где найти декларацию.
jww
9
Очевидно, это не тот же вопрос, что и связанный. «Где я что-то найду» - не то же самое, что «В чем разница между» (даже если ответ на один дает ответ на другой). Мой поиск в Google по запросу «c ++, где is size_t definition» привел меня прямо сюда, и я бы пропустил другой вопрос, потому что он другой .
stdlib.hИ stddef.hзаголовочные файлы определяют тип данных с именем size_t1 , который используется для обозначения размера объекта. Библиотечные функции, которые принимают размеры, ожидают, что они имеют тип size_t, а оператор sizeof оценивает их size_t.
Фактический тип size_tзависит от платформы; распространенной ошибкой является предположение, что size_tэто то же самое, что и unsigned int, что может привести к ошибкам программирования 2, особенно по мере того, как 64-битные архитектуры становятся все более распространенными.
Это именно то, что мне нужно, за этот ответ нужно проголосовать.
neodelphi
27
size_t представляет собой целочисленный тип без знака результата оператора sizeof (ISO C99, раздел 7.17.)
sizeofОператор дает размер (в байтах) своего операнда, который может быть выражение в скобках или имя типа. Размер определяется типом операнда. Результат - целое число. Значение результата определяется реализацией, а его тип (беззнаковый целочисленный тип) - size_t(ISO C99, раздел 6.5.3.4.)
@Martin - достаточно верно, но я думаю, что часть вопроса «почему не используется unsigned int» столь же интересна (или даже больше), как часть «что такое size_t», и вы не найдете ее в стандарте ,
Майкл Берр,
Да, вот только там нет «Раздела 17.17 »: п. Редко, никто не сказал ни слова о Void_t
Элисео Окампос
Я принимаю этот ответ, поскольку он отвечает непосредственно на вопрос, но было бы здорово, если бы он дополнялся ответом Майкла.
Элисео Окампос,
58
Жаль, что ваш ответ не говорит мне, какой файл заголовка включить.
Мэтт,
6
Фактически size_tпредставляет собой количество байтов, которые вы можете адресовать. На большинстве современных архитектур за последние 10-15 лет это было 32 бита, что также было размером беззнакового int. Однако мы переходим на 64-битную адресацию, в то время как uint, скорее всего, останется 32-битная (в стандарте C ++ ее размер не гарантируется). Чтобы ваш код, зависящий от размера памяти, переносился между архитектурами, вы должны использовать size_t. Например, такие вещи, как размеры массивов, всегда должны использовать size_t. Если вы посмотрите на стандартные контейнеры, ::size()всегда возвращает size_t.
Также обратите внимание, что в Visual Studio есть опция компиляции, которая может проверять эти типы ошибок под названием «Обнаружение проблем с 64-битной переносимостью».
Таким образом, вы всегда будете знать, какой размер, потому что размер предназначен для определенного типа. Собственный вопрос показывает, что это может быть проблема: это intили нет unsigned int? Кроме того , что величина ( short, int, longи т.д.)?
Поскольку назначен определенный тип, вам не нужно беспокоиться о длине или подписи.
size_tсоответствует интегральному типу данных, возвращаемому оператором языка, sizeofи определяется в <cstring>заголовочном файле (среди прочего) как беззнаковый интегральный тип.
В <cstring>, он используется как тип параметра numв функции memchr, memcmp, memcpy, memmove, memset, strncat, strncmp, strncpyи strxfrm, что во всех случаях используется , чтобы указать максимальное количество байтов или символов , функция должна влиять.
Он также используется в качестве возвращаемого типа для strcspn, strlen, strspnи strxfrmк размерам возврата и длины.
size_t должен быть определен в заголовках вашей стандартной библиотеки. По моему опыту, обычно это просто typedef для unsigned int. Но дело в том, что это не обязательно. Такие типы, как size_t, позволяют поставщику стандартной библиотеки свободно изменять свои базовые типы данных, если это подходит для платформы. Если вы предполагаете, что size_t всегда является целым без знака (посредством приведения и т. Д.), Вы можете столкнуться с проблемами в будущем, если ваш поставщик изменит size_t, например, на 64-битный тип. По этой причине опасно что-либо предполагать об этом или любом другом типе библиотеки.
Различные определения типов xxx_t используются для абстрагирования типа от конкретной конкретной реализации, поскольку конкретные типы, используемые для определенных вещей, могут отличаться от одной платформы к другой. Например:
size_t абстрагирует тип, используемый для хранения размера объектов, потому что в некоторых системах это будет 32-битное значение, в других - 16-битное или 64-битное.
Void_tабстрагирует тип указателя, возвращаемого vmallocбиблиотечными подпрограммами, потому что он был написан для работы в системах, предшествующих ANSI / ISO C, где voidключевое слово могло не существовать. По крайней мере, я так думаю.
wchar_t абстрагирует тип, используемый для широких символов, поскольку в некоторых системах это будет 16-битный тип, в других - 32-битный тип.
Поэтому, если вы напишете свой код обработки широких символов, чтобы использовать wchar_tтип вместо, скажем unsigned short, этого кода, вероятно, будет более переносимым на различные платформы.
Отчасти это то, что я искал. Как я сказал в комментарии к ответу fpmurphy, было бы здорово, если бы его можно было дополнить этим ответом (если вы не возражаете, возможно, вы можете его отредактировать) :)
Элисео Окампос
1
В минималистичных программах, где size_tопределение не было загружено «случайно» в некоторые включения, но оно мне все еще нужно в каком-то контексте (например, для доступа std::vector<double>), я использую этот контекст для извлечения правильного типа. Например typedef std::vector<double>::size_type size_t.
(Обведите, namespace {...}если необходимо, чтобы ограничить объем.)
Что касается «Почему бы не использовать int или unsigned int?», Просто потому, что это семантически более значимо не использовать. Есть практическая причина, по которой его можно, скажем, использовать typedefкак d, а intзатем обновить его до более longпоздней версии, конечно, без изменения кода, но более фундаментально, чем то, что тип должен быть значимым. Чтобы значительно упростить, переменная типа size_tподходит и используется для хранения размеров вещей, точно так же, как time_tи для значений времени. То, как они на самом деле реализованы, должно быть задачей самой реализации. По сравнению с простым вызовом всего int, использование таких значимых имен типов помогает прояснить смысл и цель вашей программы, как это делает любой богатый набор типов.
Ответы:
Из Википедии
Начиная с C99 7.17.1 / 2
источник
int
иunsigned int
типы 32 бита, а size_t составляет 64 бита.Согласно описанию size_t на en.cppreference.com
size_t
определены следующие заголовки:источник
size_t
представляет собой целочисленный тип без знака результата оператора sizeof (ISO C99, раздел 7.17.)sizeof
Оператор дает размер (в байтах) своего операнда, который может быть выражение в скобках или имя типа. Размер определяется типом операнда. Результат - целое число. Значение результата определяется реализацией, а его тип (беззнаковый целочисленный тип) -size_t
(ISO C99, раздел 6.5.3.4.)источник
Фактически
size_t
представляет собой количество байтов, которые вы можете адресовать. На большинстве современных архитектур за последние 10-15 лет это было 32 бита, что также было размером беззнакового int. Однако мы переходим на 64-битную адресацию, в то время какuint
, скорее всего, останется 32-битная (в стандарте C ++ ее размер не гарантируется). Чтобы ваш код, зависящий от размера памяти, переносился между архитектурами, вы должны использоватьsize_t
. Например, такие вещи, как размеры массивов, всегда должны использоватьsize_t
. Если вы посмотрите на стандартные контейнеры,::size()
всегда возвращаетsize_t
.Также обратите внимание, что в Visual Studio есть опция компиляции, которая может проверять эти типы ошибок под названием «Обнаружение проблем с 64-битной переносимостью».
источник
Таким образом, вы всегда будете знать, какой размер, потому что размер предназначен для определенного типа. Собственный вопрос показывает, что это может быть проблема: это
int
или нетunsigned int
? Кроме того , что величина (short
,int
,long
и т.д.)?Поскольку назначен определенный тип, вам не нужно беспокоиться о длине или подписи.
Фактическое определение можно найти в Справочной библиотеке C ++ , в которой говорится:
источник
size_t должен быть определен в заголовках вашей стандартной библиотеки. По моему опыту, обычно это просто typedef для unsigned int. Но дело в том, что это не обязательно. Такие типы, как size_t, позволяют поставщику стандартной библиотеки свободно изменять свои базовые типы данных, если это подходит для платформы. Если вы предполагаете, что size_t всегда является целым без знака (посредством приведения и т. Д.), Вы можете столкнуться с проблемами в будущем, если ваш поставщик изменит size_t, например, на 64-битный тип. По этой причине опасно что-либо предполагать об этом или любом другом типе библиотеки.
источник
Я не знаком с ,
void_t
кроме как в результате поиска Google (он используется в видеvmalloc
библиотеки по Кию-Фонг Vo в AT & T Research - Я уверен , что он используется в других библиотеках, а).Различные определения типов xxx_t используются для абстрагирования типа от конкретной конкретной реализации, поскольку конкретные типы, используемые для определенных вещей, могут отличаться от одной платформы к другой. Например:
Void_t
абстрагирует тип указателя, возвращаемогоvmalloc
библиотечными подпрограммами, потому что он был написан для работы в системах, предшествующих ANSI / ISO C, гдеvoid
ключевое слово могло не существовать. По крайней мере, я так думаю.wchar_t
абстрагирует тип, используемый для широких символов, поскольку в некоторых системах это будет 16-битный тип, в других - 32-битный тип.Поэтому, если вы напишете свой код обработки широких символов, чтобы использовать
wchar_t
тип вместо, скажемunsigned short
, этого кода, вероятно, будет более переносимым на различные платформы.источник
В минималистичных программах, где
size_t
определение не было загружено «случайно» в некоторые включения, но оно мне все еще нужно в каком-то контексте (например, для доступаstd::vector<double>
), я использую этот контекст для извлечения правильного типа. Напримерtypedef std::vector<double>::size_type size_t
.(Обведите,
namespace {...}
если необходимо, чтобы ограничить объем.)источник
Что касается «Почему бы не использовать int или unsigned int?», Просто потому, что это семантически более значимо не использовать. Есть практическая причина, по которой его можно, скажем, использовать
typedef
как d, аint
затем обновить его до болееlong
поздней версии, конечно, без изменения кода, но более фундаментально, чем то, что тип должен быть значимым. Чтобы значительно упростить, переменная типаsize_t
подходит и используется для хранения размеров вещей, точно так же, какtime_t
и для значений времени. То, как они на самом деле реализованы, должно быть задачей самой реализации. По сравнению с простым вызовом всегоint
, использование таких значимых имен типов помогает прояснить смысл и цель вашей программы, как это делает любой богатый набор типов.источник