sizeof — унарная операция, возвращающая размер в байтах. Применённая к
типу, даёт размер объекта этого типа; применённая к выражению — размер типа
его результата. Выражение при этом не вычисляется.
Зачем нужно
Размеры типов в C++ стандартом не зафиксированы — sizeof(long) на Windows и
Linux разный (см. Целочисленные типы). sizeof узнаёт размер для текущей
платформы. Он же нужен для подсчёта байт при ручном выделении памяти и для
арифметики указателей, где шаг — sizeof(T).
Как работает
long long x;
sizeof(int); // размер типа
sizeof('a'); // 1
sizeof(1 / 0); // 4
sizeof(x = 1); // 8 (x не меняется!)
sizeof(++x); // 8 (x не меняется!)Операнд sizeof компилятор только анализирует: определяет тип выражения и
подставляет его размер. Деления на ноль во второй строке нет, присваивания в
третьей тоже нет — код для них не генерируется.
sizeof(char) равен единице по определению — это и есть байт C++, см.
Символьный тип char.
Тонкости
sizeof(x + y)для двухshortравен 4: тип выражения —intпосле продвижения, см. Арифметические преобразования типов.- Скобки обязательны для типа (
sizeof(int)), для выражения не обязательны:sizeof x.
Не из лекции
- Последний пункт в лонгриде не упоминается.
- Результат имеет беззнаковый тип
std::size_t— со всеми ловушками беззнаковых при сравнении с отрицательными числами.
Частые ошибки
- Писать побочный эффект внутри
sizeofи ждать, что он выполнится. - Считать, что размер типа одинаков на всех платформах.
Углубление — L04
Для массива sizeof возвращает суммарный размер, отсюда способ
посчитать элементы:
int array[10];
sizeof(array); // 40
sizeof(array) / sizeof(int); // 10Это одно из мест, где массив не превращается в указатель. Для указателя на тот же массив результат другой:
int* p = array;
sizeof(p); // 8То же с динамическим массивом: new[] возвращает
указатель, и sizeof(new int[10]) == sizeof(int*). Сама строка ничего не
выделяет — операнд sizeof не вычисляется.