Оператор sizeof
Опрашивает размер объекта или типа.
Используется, когда необходимо узнать фактический размер объекта.
Синтаксис
sizeof( тип ) | (1) | |
sizeof выражение | (2) |
Оба варианта являются константными выражениями типа std::size_t.
| тип | - | идентификатор типа (см. имена типов) |
| выражение | - | выражение, приоритет которого не ниже sizeof (например, sizeof a + b разбирается как (sizeof a) + b вместо sizeof (a + b)) |
Объяснение
Примечания
В зависимости от архитектуры компьютера, байт может состоять из 8 или более бит, точное количество которых записано в CHAR_BIT.
Следующие sizeof выражения всегда вычисляются в 1:
-
sizeof(char) -
sizeof(signed char) -
sizeof(unsigned char)
| (с C++17) |
| (с C++20) |
sizeof не может быть использован с типами функций, неполными типами или битовыми полями lvalues(до C++11)glvalues(с C++11).
При применении к типу ссылки результатом является размер ссылаемого типа.
При применении к типу класса результатом является число байт, занимаемых полным объектом этого класса, включая любые дополнительные поля, необходимые для размещения такого объекта в массиве. Количество байт, занимаемых потенциально перекрывающимся подобъектом, может быть меньше размера этого объекта.
Результат sizeof всегда отличен от нуля, даже если применён к пустому типу класса.
При применении к выражению, sizeof не вычисляет выражение (т.е. выражение является невычисляемым операндом)(с C++11), и даже если выражение обозначает полиморфный объект, результатом является размер статического типа выражения. Преобразования lvalue-в-rvalue, массива-в-указатель или функции-в-указатель не выполняются. Однако, временная материализация выполняется (формально) для аргументов prvalue: программа является некорректной, если аргумент не является разрушаемым.(с C++17)
Ключевые слова
Пример
Вывод примера соответствует системе с 64-битными указателями и 32-битными целыми числами (также известной как LP64 или LLP64).
#include <cstdlib>
#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(); // the return type is Empty, but always throws 1
auto println = [](auto rem, std::size_t size) { std::cout << rem << size << '\n'; };
println( "1) sizeof empty class: ", sizeof e );
println( "2) sizeof pointer: ", sizeof &e );
println( "3) sizeof(Bit) class: ", sizeof(Bit) );
println( "4) sizeof(int[10]) array of 10 int: ", sizeof(int[10]) );
println( "5) sizeof a array of 10 int: ", sizeof a );
println( "6) length of array of 10 int: ", ((sizeof a) / (sizeof *a)) );
println( "7) length of array of 10 int (2): ", ((sizeof a) / (sizeof a[0])) );
println( "8) sizeof the Derived class: ", sizeof d );
println( "9) sizeof the Derived through 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 function: ", sizeof(void()) ); // error
// println( "sizeof incomplete type: ", sizeof(int[]) ); // error
// println( "sizeof bit-field: ", sizeof bit.bit ); // error
}Возможный вывод:
1) sizeof empty class: 1 2) sizeof pointer: 8 3) sizeof(Bit) class: 4 4) sizeof(int[10]) array of 10 int: 40 5) sizeof a array of 10 int: 40 6) length of array of 10 int: 10 7) length of array of 10 int (2): 10 8) sizeof the Derived class: 8 9) sizeof the Derived through 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++.
| DR | Применено к | Поведение, как опубликовано | Корректное поведение |
|---|---|---|---|
| CWG 1122 | C++98 | тип результата sizeof (std::size_t) был циклически определён | он определяется так же, как и в C |
| CWG 1553 | C++11 |
sizeof мог использоваться с битовыми xvalues | запрещено |
См. также
alignof оператор(C++11) | опрашивает требования выравнивания типа |
sizeof... оператор(C++11) | опрашивает количество элементов в пакете параметров |
| предоставляет интерфейс для запроса свойств всех фундаментальных числовых типов (шаблон класса) |
|
C документация для sizeof |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/sizeof