Что такое sizeof(size_t) для 32-битных и различных 64-битных моделей данных?

В 64-битной системе sizeof(unsigned long) зависит от модели данных, реализованной системой, например, это 4 байта в LLP64 (Windows), 8 байтов в LP64 (Linux и т. д.). Каким должен быть sizeof(size_t)? Зависит ли это от модели данных, как sizeof(long)? Если да, то как?


Использованная литература:

64 -битные модели данных в Википедии


person Community    schedule 28.05.2009    source источник
comment
MSDN на Общие проблемы миграции 64-разрядной версии Visual C++ полезен для Windows 64.   -  person Jonathan Leffler    schedule 25.04.2014


Ответы (4)


size_t определяется стандартом C как целое без знака, возвращаемое оператором sizeof (C99 6.3.5.4.4) и аргументом malloc и его друзей (C99 7.20.3.3 и т. д.). Фактический диапазон устанавливается таким, чтобы максимальное значение (SIZE_MAX) составляло не менее 65 535 (C99 7.18.3.2).

Однако это не позволяет нам определить sizeof(size_t). Реализация может использовать любое представление для size_t, которое ей нравится, поэтому верхней границы размера нет, и реализация также может определять байт как 16-битный, и в этом случае size_t может быть эквивалентен беззнаковому символу.

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

`-mcmodel=small'
     Generate code for the small code model: the program and its
     symbols must be linked in the lower 2 GB of the address space.
     Pointers are 64 bits.  Programs can be statically or dynamically
     linked.  This is the default code model.

`-mcmodel=kernel'
     Generate code for the kernel code model.  The kernel runs in the
     negative 2 GB of the address space.  This model has to be used for
     Linux kernel code.

`-mcmodel=medium'
     Generate code for the medium model: The program is linked in the
     lower 2 GB of the address space but symbols can be located
     anywhere in the address space.  Programs can be statically or
     dynamically linked, but building of shared libraries are not
     supported with the medium model.

`-mcmodel=large'
     Generate code for the large model: This model makes no assumptions
     about addresses and sizes of sections.

Вы заметите, что указатели во всех случаях являются 64-битными; и в конце концов нет смысла иметь 64-битные указатели, но не 64-битные размеры.

person bdonlan    schedule 28.05.2009

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

person Evan Teran    schedule 28.05.2009

size_t обычно 64-битный на 64-битной машине

person adwords    schedule 28.05.2009

РЕДАКТИРОВАНИЕ: Спасибо за комментарии — я посмотрел в стандарт C99, который гласит в разделе 6.5.3.4:

Значение результата определяется реализацией, а его тип (целочисленный тип без знака) — size_t, определенный в <stddef.h> (и других заголовках).

Таким образом, размер size_t не указан, только то, что это должен быть целочисленный тип без знака. Однако интересную спецификацию можно найти в главе 7.18.3 стандарта:

предел size_t

SIZE_MAX 65535

Это в основном означает, что независимо от размера size_t допустимый диапазон значений составляет от 0 до 65535, остальное зависит от реализации.

person beef2k    schedule 28.05.2009
comment
Я не думаю, что это определение верно: size_t — это просто тип результата оператора sizeof, и он должен быть беззнаковым. - person Evan Teran; 28.05.2009
comment
Я думаю, вы перепутали, где объект с (его адресом/указателем) с его размером (size_t). - person Evan Teran; 28.05.2009
comment
@beef2k, вы, конечно, не можете сказать это в C. В C объект просто представляет собой область хранения, которая по своей сути не имеет типа. Вы можете использовать calloc для создания объектов большего размера, чем может представлять size_t. - person Johannes Schaub - litb; 28.05.2009
comment
@beef2k: Ваше последнее утверждение технически неверно. Вы не можете сказать, что sizeof(size_t) обязательно = 2, потому что реализация может решить определить байт как 32-битный, и в этом случае sizeof(size_t) может легко быть 1. - person user83255; 28.05.2009
comment
Для пояснения: SIZE_MAX — это один из макросов в 7.18.3.2, определяемое реализацией значение которого должно быть равно или больше по величине (абсолютное значение), чем соответствующее значение, указанное ниже, с тем же знаком. , то есть 65535 — это минимальное значение, которое является приемлемым пределом для размера size_t, но оно может быть (и обычно бывает) намного больше. - person anol; 15.12.2015