Оператор sizeof
Запрашивает размер объекта или типа.
Используется, когда необходимо знать фактический размер объекта.
Синтаксис
sizeof( тип )
|
(1) | ||||||||
sizeof выражение
|
(2) | ||||||||
Обе версии являются константными выражениями типа std::size_t.
Объяснение
Примечание
В зависимости от архитектуры компьютера байт может состоять из 8 или более битов, точное число записывается в CHAR_BIT.
Следующие выражения sizeof всегда дают результат 1:
sizeof(char)sizeof(signed char)sizeof(unsigned char)
|
(начиная с C++17) |
|
(начиная с C++20) |
sizeof нельзя использовать с функциональными типами, неполными типами или битовых полей lvalue (до C++11)glvalue (начиная с C++11).
При применении к ссылочному типу результатом является размер ссылочного типа.
При применении к типу класса результатом является количество байтов, занятых полным объектом этого класса, включая любые дополнительные отступы, необходимые для размещения такого объекта в массиве. Количество байтов, занимаемых потенциально перекрывающимся подобъектом, может быть меньше размера этого объекта.
Результат sizeof всегда отличен от нуля, даже если он применяется к пустому типу класса.
При применении к выражению sizeof не оценивает выражение, и даже если выражение обозначает полиморфный объект, результатом является размер статического типа выражения. Преобразования lvalue-в-rvalue, массива в указатель или функции в указатель не выполняются. Однако временная материализация выполняется (формально) для аргументов prvalue: программа некорректна, если аргумент не разрушаем. (начиная с C++17)
Ключевые слова
Пример
Пример вывода соответствует системе с 64-битными указателями и 32-битным int.
#include <iostream>
struct Empty {};
struct Base { int a; };
struct Derived : Base { int b; };
struct Bit { unsigned bit: 1; };
struct CharChar { char c; char c2; };
struct CharCharInt { char c; char c2; int i; };
struct IntCharChar { int i; char c; char c2; };
struct CharIntChar { char c; int i; char c2; };
struct CharShortChar { char c; short s; char c2; };
int main()
{
Empty e;
Derived d;
Base& b = d;
[[maybe_unused]] Bit bit;
int a[10];
auto f = [&]() { return sizeof(int[10]) == sizeof a ? throw 1 : e; };
// f(); // тип возвращаемого значения Empty, но всегда генерирует исключение 1
auto println = [](auto rem, std::size_t size) { std::cout << rem << size << '\n'; };
println( "1) размер пустого класса: ", sizeof e );
println( "2) размер указателя: ", sizeof &e );
println( "3) sizeof(Bit) класса: ", sizeof(Bit) );
println( "4) sizeof(int[10]) массива из 10 int: ", sizeof(int[10]) );
println( "5) sizeof a массива из 10 int: ", sizeof a );
println( "6) длина массива из 10 int: ", ((sizeof a) / (sizeof *a)) );
println( "7) длина массива из 10 int (2): ", ((sizeof a) / (sizeof a[0])) );
println( "8) размер класса Derived: ", sizeof d );
println( "9) размер Derived через Base: ", sizeof b );
println( "A) sizeof(unsigned): ", sizeof(unsigned) );
println( "B) sizeof(int): ", sizeof(int) );
println( "C) sizeof(short): ", sizeof(short) );
println( "D) sizeof(char): ", sizeof(char) );
println( "E) sizeof(CharChar): ", sizeof(CharChar) );
println( "F) sizeof(CharCharInt): ", sizeof(CharCharInt) );
println( "G) sizeof(IntCharChar): ", sizeof(IntCharChar) );
println( "H) sizeof(CharIntChar): ", sizeof(CharIntChar) );
println( "I) sizeof(CharShortChar): ", sizeof(CharShortChar) );
println( "J) sizeof f(): ", sizeof f() );
println( "K) sizeof Base::a: ", sizeof Base::a );
// println( "размер функции: ", sizeof(void()) ); // ошибка
// println( "размер неполного типа: ", sizeof(int[]) ); // ошибка
// println( "размер битового поля: ", sizeof bit.bit ); // ошибка
}
Возможный вывод:
1) размер пустого класса: 1
2) размер указателя: 8
3) sizeof(Bit) класса: 4
4) sizeof(int[10]) массива из 10 int: 40
5) sizeof a массива из 10 int: 40
6) длина массива из 10 int: 10
7) длина массива из 10 int (2): 10
8) размер класса Derived: 8
9) размер Derived через Base: 4
A) sizeof(unsigned): 4
B) sizeof(int): 4
C) sizeof(short): 2
D) sizeof(char): 1
E) sizeof(CharChar): 2
F) sizeof(CharCharInt): 8
G) sizeof(IntCharChar): 8
H) sizeof(CharIntChar): 12
I) sizeof(CharShortChar): 6
J) sizeof f(): 1
K) sizeof Base::a: 4
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| CWG 1122 | C++98 | тип результата sizeof (std::size_t) был определён циклически
|
он определяется так же, как в C |
| CWG 1553 | C++11 | sizeof можно использовать с битовыми полями значений xvalue
|
запрещено |
Смотрите также
оператор alignof(C++11)
|
запрашивает требования к выравниванию типа |
sizeof... operator(C++11)
|
запрашивает количество элементов в пакете параметров |
| предоставляет интерфейс для запроса свойств всех основных числовых типов. (шаблон класса) | |
Документация C по sizeof
| |