В каких единицах измеряется sizeof в C++
Что проверяют
Знаете ли вы, что такое байт с точки зрения стандарта C++ и чем размер типа отличается от объёма данных. Ответ «в байтах» верный, но интервьюер почти всегда идёт дальше: сколько бит в байте, чему равен sizeof структуры и почему массив внутри функции вдруг «уменьшился».
Как отвечать
sizeof возвращает размер в байтах, значение типа std::size_t, вычисляется на этапе компиляции. Дальше детали:
- байт в C++: это размер
char,sizeof(char)равен 1 по определению. Число бит в байте задаётCHAR_BITиз<climits>, стандарт требует не меньше 8, на практике почти всегда ровно 8; - модель данных:
intна массовых платформах 4 байта, аlongна 64-битном Linux 8 (LP64), на 64-битной Windows 4 (LLP64). Стандарт гарантирует лишь минимальные диапазоны и порядокsizeof(short) <= sizeof(int) <= sizeof(long). Нужен точный размер, беритеstd::int32_tиstd::int64_t; - выравнивание:
struct { char c; int i; }обычно занимает 8 байт, а не 5, из-за паддинга. Требование узнают черезalignof, а поля от крупных к мелким уменьшают потери; - пустой класс:
sizeofне меньше 1, чтобы у разных объектов были разные адреса; - массив и указатель: для
int arr[10]получите10 * sizeof(int), но в параметре функции массив становится указателем, иsizeofвернёт размер указателя; - операнд не вычисляется:
sizeof(f())не вызываетf, берётся только тип результата.
sizeof(std::vector<int>) показывает размер самого объекта с указателями, а не данных в куче. Число элементов даёт size(), для массива удобен std::size(arr) из C++17.
Где спотыкаются
Говорят, что sizeof(int) бывает 4 или 8 в зависимости от разрядности. На x86-64 и ARM64 в обеих популярных моделях он равен 4, с разрядностью меняются long и указатели.
Считают байт синонимом восьми бит без оговорок. Для практики это верно, но стандарт определяет байт через char и CHAR_BIT.
Пишут в функции sizeof(arr) / sizeof(arr[0]) для переданного массива и на 64-битной платформе получают 2 вместо длины. Параметр уже указатель.