Подтвердить что ты не робот

Размер size_t - размер слова?

Является ли size_t размер слова машины, который скомпилировал код?

Разбор с g++, мои компиляторы видят size_t как long unsigned int. Является ли компилятор внутренне выбирать размер size_t или size_t на самом деле typdefed внутри некоторого макропроцессора в stddef.h до размера слова перед вызовом компилятора?

Или я не в курсе?

4b9b3361

Ответ 1

В стандарте С++ [support.types] (18.2)/6: "Тип size_t представляет собой целочисленный тип без знака, определенный для реализации, который достаточно велик, чтобы содержать размер в байтах любого объекта".

Это может быть или не быть таким же, как "размер слова", что бы это ни значило.

Ответ 2

Нет; size_t не обязательно означает, что вы имеете в виду "размер слова" машины, которая будет запускать код (в случае кросс-компиляции) или скомпилировать код (в обычном случае, когда код будет работать на том же тип машины, которая скомпилировала код). Это целочисленный тип без знака, достаточно большой для хранения размера (в байтах) самого большого объекта, который может выделить реализация.


Некоторая история sizeof и size_t

Я не знаю, когда было введено size_t точно, но это было между 1979 и 1989 годами. Первое издание K & R Язык программирования C с 1978 года не упоминает size_t. В 7-м издании Unix Programmer Manual нет упоминания о size_t вообще, и это датируется 1979 годом. Книга "Среда программирования UNIX" Кернигана и Пайка с 1984 года не упоминает size_t в индексе (или malloc() или free(), к моему удивлению), но это только показательно, а не окончательно. Стандарт C89, безусловно, имеет size_t.

Обоснование C99 документирует некоторую информацию о sizeof() и size_t:

6.5.3.4 Оператор sizeof

Это фундаментальное значение для правильного использования таких функций, как malloc и fread, что sizeof(char) будет ровно одним. На практике это означает, что байт в терминах C является наименьшим единица хранения, даже если этот блок имеет ширину 36 бит; и все объекты состоят из целого количество этих наименьших единиц. Также применяется, если память адресована битом. C89, как и K & R, определил результат оператора sizeof как константу целочисленного типа без знака. Общие реализации и общее использование часто предполагали, что результирующий тип int. Старый код, который зависит от этого поведения, никогда не был которые определяют результат как тип, отличный от int. Комитет С89 не считают правильным изменить язык, чтобы защитить неправильный код.

Тип sizeof, независимо от того, что он есть, публикуется (в заголовке библиотеки <stddef.h>) как  size_t, поскольку для программиста полезно иметь возможность ссылаться на этот тип. Это требование неявно ограничивает size_t как синоним существующего целочисленного типа без знака. Примечание. что, хотя size_t является неподписанным типом, sizeof не включает никаких арифметических операций или преобразования, которые приведут к поведению модуля, если размер слишком велик, чтобы представлять в виде size_t, тем самым отменив любое представление о том, что наибольший декларируемый объект может быть слишком большим для охвата даже с unsigned long в C89 или uintmax_t на C99. Это также ограничивает максимальное количество элементов, которые могут быть объявлены в массиве, так как для любого массива a of Nэлементы,

N == sizeof(a)/sizeof(a[0])

Таким образом, size_t также является удобным типом для размеров массива и поэтому используется в нескольких библиотечных функциях. [...]

7.17 Общие определения

<stddef.h> - это заголовок, созданный для определения определений нескольких типов и макросов, используемых широко в сочетании с библиотекой: ptrdiff_t, size_t, wchar_t и NULL. Включая любой заголовок, который ссылается на один из этих макросов, также определит его, исключение из обычное правило библиотеки, что каждый макрос или функция принадлежит ровно одному заголовку.

Обратите внимание, что это специально указывает, что <stddef.h> был изобретен комитетом C89. Я не нашел слов, которые говорят, что size_t также был изобретен комитетом C89, но если это не так, это была кодификация довольно недавней разработки в C.


В комментарии к bmargulies answer, vonbrand говорит, что 'it [size_t], безусловно, является ANSI-C-ism'. Я могу с легкостью поверить, что это была новация с оригинальным ANSI (ISO) C, хотя, мягко говоря, в рассуждении это не сказано.

Ответ 3

Не обязательно. Спецификация C ISO (& section 17.1/2) определяет size_t как

size_t, который представляет собой целочисленный тип без знака результата оператора sizeof

Другими словами, size_t должен быть достаточно большим, чтобы удерживать размер любого выражения, которое может быть получено из sizeof. Это может быть размер машинного слова, но он может быть значительно меньше (если, например, компилятор ограничивает максимальный размер массивов или объектов) или значительно больше (если компилятор должен был создавать объекты настолько огромными, что одна машина слово не могло сохранить размер этого объекта).

Надеюсь, это поможет!

Ответ 4

size_t был, или, как правило, просто typedef в sys/types.h(традиционно в Unix/Linux). Предполагалось, что он "достаточно большой", например, для максимального размера файла или максимального распределения с помощью malloc. Тем не менее, со временем стандартные комитеты схватили его, и поэтому он был скопирован во множество разных файлов заголовков, каждый раз защищенный своей защитой #ifdef от множественного определения. С другой стороны, появление 64-битных систем с очень большими потенциальными размерами файлов затормозило свою роль. Так что это немного палимпсет.

Теперь стандарты языка теперь называются живыми в stddef.h. Он не имеет никакого отношения к размеру аппаратного слова и магии компилятора. См. Другие ответы относительно того, что эти стандарты говорят о том, насколько они велики.

Ответ 5

Такие определения определяются реализацией. Я бы использовал sizeof (char *), или, может быть, sizeof (void *), если бы мне нужен максимальный размер угадывания. Лучшее, что дает это, - это очевидное программное обеспечение для определения размера слова... то, что аппаратное обеспечение действительно может быть другим (например, 32-разрядная система может поддерживать 64-разрядные целые числа по программному обеспечению).

Также, если вы новичок в языках C, см. stdint.h для всех видов материала на целочисленных размерах.

Ответ 6

Хотя в определении прямо не указано, какой тип точно size_t, и даже не требует минимального размера, он косвенно дает некоторые хорошие подсказки. A size_t должен иметь возможность содержать размер в байтах любого объекта, другими словами, он должен иметь возможность содержать размер максимально возможного объекта.

Самый большой возможный объект - это массив (или структура) с размером, равным всему доступному адресному пространству. Невозможно ссылаться на более крупный объект значимым образом, и помимо доступности пространства подкачки нет причин, по которым он должен быть меньше.

Следовательно, по формулировке определения size_t должно быть не менее 32 бит в 32-битной архитектуре и не менее 64 бит в 64-битной системе. Конечно, для реализации можно выбрать более крупный size_t, но это обычно не так.