Skip to the content.

О выборе размера типа


Как известно, память компьютера - множество ячеек размера один байт, каждая из которых имеет свой адрес. Стоит сразу отметить, что переменная может занимать больше 1 байта в памяти: 2, 4, 8 и больше ячеек. Сколько памяти занимает переменная зависит от её типа данных. Также стоит упомянуть, из комбинаторики: в n бит можно записать 2n различных значений. Когда мы объявляем переменную, то память под неё выделяется до тех пор, пока она существует. В современных условиях, когда памяти у компьютеров очень много, никто не беспокоится о размере переменных, однако в очень больших программах с множеством переменных разница между использованием переменных разных размеров может быть уже более заметной.

Из заметки про встроенные типы данных стало понятно что размер определенного типа зависит от арихитектуры и компилятора, а С++ гарантирует только минимальный размер типа. Чтобы узнать фактический размер на текущей машине используют оператор sizeof (Забавно, что sizeof это один из трех операторов, который является словом, а не символом. Остальные два: new и delete).

Конкретных правил по выбору размера типа несуществует, однако каждый раз при объявлении новой переменной стоит задумываться о её возможных значениях: хватит ли текущего размера, не будет ли она когда-то больше чем размер типа. В большинстве ситуаций лучше использовать обычный int, который зачастую представлен 32-битами (точно не больше чем 32), если не хватает обычного 32-битного int, лучше использовать int64_t.

Целочисленные типы данных с фиксированным размером


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

Однако, как оказалось, такая система не всегда удобная. Чтобы решить вопрос кроссплатформенности в яп С++ добавили целочисленные типы фиксированного размера - с одним и тем же размером на любой архитектуре.

Файл заголовков:

Тип Размер
signed
int8_t 1 байт
int16_t 2 байта
int32_t 4 байта
int64_t 8 байт
intptr_t размером с указатель
unsigned
uint8_t 1 байт
uint16_t 2 байта
uint32_t 4 байта
uint64_t 8 байт
uintptr_t размером с указатель

ВНИМАНИЕ! На многих платформах int8_t и uint8_t определены как unsigned char и соответственно обрабатываются так же. Лучше вместо них использовать int16_t и uint16_t либо быть очень внимательным:

std::int8_t a = 65;
std::cout << a << std::endl; \\ выведет A, хотя ожидали 65

От чего зависит размер указателя\ссылки


Размер указателя, как и многое в С++, не имеет фиксированного стандартом размера. В большинстве современных ОС используются модели данных, в которых размер указателя соответствует разрядности адресной шины.

Ширина шины адреса определяет максимально возможный размер адреса. В середине 1970-х годов типовая ширина шины данных составляла 8 бит. В наше время это обычно 32,64 или 128 бит. Элемент данных, задействующий всю ширину шины, принято называть словом.

bus

Адресная шина

Соответственно, размер указателя чаще всего:

Главное что нужно помнить: типы данных, размер которых больше чем размер указателя, нужно передавать (например, в функции) по указателю\ссылке, чтобы избежать лишнего копирования.