Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/sizeof"

From cppreference.com
< cpp‎ | language
(See also: fmt)
m (Notes: fix spacing)
 
(20 intermediate revisions by 6 users not shown)
Line 1: Line 1:
{{title|sizeof operator}}
+
{{title|{{tt|sizeof}} operator}}
 
{{cpp/language/expressions/navbar}}
 
{{cpp/language/expressions/navbar}}
 
Queries size of the object or type.
 
Queries size of the object or type.
Line 6: Line 6:
  
 
===Syntax===
 
===Syntax===
 
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc | num=1 | {{ttb|sizeof(}} {{spar|type}} {{ttb|)}}}}
+
{{sdsc|num=1|{{ttb|sizeof(}} {{spar|type}} {{ttb|)}}}}
{{sdsc | num=2 | {{ttb|sizeof}} {{spar|expression}} {{ttb|}}}}
+
{{sdsc|num=2|{{ttb|sizeof}} {{spar|expression}} {{ttb|}}}}
 
{{sdsc end}}
 
{{sdsc end}}
  
Both versions are constant expressions of type {{lc|std::size_t}}.  
+
Both versions are constant expressions of type {{lc|std::size_t}}.
  
===Explanation===
+
{{par begin}}
 +
{{par|{{spar|type}}|a {{spar|type-id}} (see {{rlp|type#Type naming|type naming}})}}
 +
{{par|{{spar|expression}}|an expression whose {{rlp|operator precedence}} is not lower than {{tt|sizeof}} (e.g. {{c|sizeof a + b}} is parsed as {{c|(sizeof a) + b}} instead of {{c|sizeof (a + b)}})}}
 +
{{par end}}
  
 +
===Explanation===
 
@1@ Yields the size in bytes of the {{rlp|object|object representation}} of {{spar|type}}.
 
@1@ Yields the size in bytes of the {{rlp|object|object representation}} of {{spar|type}}.
 
@2@ Yields the size in bytes of the object representation of the type of {{spar|expression}}, if that expression is evaluated.
 
@2@ Yields the size in bytes of the object representation of the type of {{spar|expression}}, if that expression is evaluated.
  
 
===Notes===
 
===Notes===
Depending on the computer architecture, a [[enwiki:Byte|byte]] may consist of 8 ''or more'' bits, the exact number being recorded in {{lc|CHAR_BIT}}.
+
Depending on the computer architecture, a {{enwiki|byte}} may consist of 8 ''or more'' bits, the exact number being recorded in {{lc|CHAR_BIT}}.
  
 
The following {{tt|sizeof}} expressions always evaluate to {{c|1}}:
 
The following {{tt|sizeof}} expressions always evaluate to {{c|1}}:
Line 26: Line 29:
 
* {{c|sizeof(signed char)}}
 
* {{c|sizeof(signed char)}}
 
* {{c|sizeof(unsigned char)}}
 
* {{c|sizeof(unsigned char)}}
{{rrev|since=c++17|* {{c|sizeof(std::byte)}}}}
+
{{rev begin}}
{{rrev|since=c++20|* {{c|sizeof(char8_t)}}}}
+
{{rev|since=c++17|
 +
* {{c|sizeof(std::byte)}}
 +
}}
 +
{{rev|since=c++20|
 +
* {{c|sizeof(char8_t)}}
 +
}}
 +
{{rev end}}
  
{{tt|sizeof}} cannot be used with function types, incomplete types, or bit-field glvalues.
+
{{tt|sizeof}} cannot be used with function types, incomplete types, or bit-field {{rev inl|until=c++11|lvalues}}{{rev inl|since=c++11|glvalues}}.
  
 
When applied to a reference type, the result is the size of the referenced type.
 
When applied to a reference type, the result is the size of the referenced type.
Line 37: Line 46:
 
The result of {{tt|sizeof}} is always nonzero, even if applied to an empty class type.
 
The result of {{tt|sizeof}} is always nonzero, even if applied to an empty class type.
  
When applied to an expression, {{tt|sizeof}} does {{rlp|expressions#Unevaluated_expressions|not evaluate the expression}}, and even if the expression designates a polymorphic object, the result is the size of the static type of the expression. Lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversions are not performed. {{rev inl|since=c++17|{{rlp|implicit_conversion#Temporary_materialization|Temporary materialization}}, however, is (formally) performed for prvalue arguments: the program is ill-formed if the argument is not destructible.}}
+
When applied to an expression, {{tt|sizeof}} does {{rlp|expressions#Potentially-evaluated expressions|not evaluate the expression}}{{rev inl|since=c++11| (i.e. the expression is an unevaluated operand)}}, and even if the expression designates a polymorphic object, the result is the size of the static type of the expression. Lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversions are not performed.{{rev inl|since=c++17| {{rlp|implicit conversion#Temporary materialization|Temporary materialization}}, however, is (formally) performed for prvalue arguments: the program is ill-formed if the argument is not destructible.}}
  
 
===Keywords===
 
===Keywords===
Line 44: Line 53:
 
===Example===
 
===Example===
 
{{example
 
{{example
| The example output corresponds to a system with 64-bit pointers and 32-bit int.
+
|The example output corresponds to a system with 64-bit pointers and 32-bit int (a.k.a. {{rlp|types#Data models|'''LP64''' or '''LLP64'''}}).
| code=
+
|code=
 +
#include <cstdlib>
 
#include <iostream>
 
#include <iostream>
  
struct Empty {};
+
struct Empty         { };
struct Base { int a; };
+
struct Base           { int a; };
 
struct Derived : Base { int b; };
 
struct Derived : Base { int b; };
struct Bit { unsigned bit: 1; };
+
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()
 
int main()
Line 60: Line 75:
 
     [[maybe_unused]] Bit bit;
 
     [[maybe_unused]] Bit bit;
 
     int a[10];
 
     int a[10];
     std::cout
+
      
      << "1) size of empty class:              " << sizeof e        << '\n'
+
    auto f = [&]() { return sizeof(int[10]) == sizeof a ? throw 1 : e; };
      << "2) size of pointer:                  " << sizeof &e       << '\n'
+
// f(); // the return type is Empty, but always throws 1
//   << "3) size of function:                 " << sizeof(void())  << '\n' // error
+
   
//    << "4) size of incomplete type:         " << sizeof(int[])   << '\n' // error
+
    auto println = [](auto rem, std::size_t size) { std::cout << rem << size << '\n'; };
//    << "5) size of bit field:               " << sizeof bit.bit  << '\n' // error
+
   
      << "6) size of Bit class:               " << sizeof(Bit)    << '\n'
+
    println( "1) sizeof empty class:             ", sizeof e                    );
      << "7) size of array of 10 int:         " << sizeof(int[10]) << '\n'
+
    println( "2) sizeof pointer:                 ", sizeof &e                    );
      << "8) size of array of 10 int (2):     " << sizeof a       << '\n'
+
    println( "3) sizeof(Bit) class:               ", sizeof(Bit)                 );
      << "9) length of array of 10 int:       " << ((sizeof a) / (sizeof *a))  << '\n'
+
     println( "4) sizeof(int[10]) array of 10 int: ", sizeof(int[10])             );
      << "A) length of array of 10 int (2):   " << ((sizeof a) / (sizeof a[0])) << '\n'
+
    println( "5) sizeof a        array of 10 int: ", sizeof a                     );
      << "B) size of the Derived:             " << sizeof d       << '\n'
+
    println( "6) length of array of 10 int:       ", ((sizeof a) / (sizeof *a))  );
      << "C) size of the Derived through Base: " << sizeof b        << '\n';
+
    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
 
}
 
}
| p=true
+
|p=true
| output=
+
|output=
1) size of empty class:              1
+
1) sizeof empty class:              1
2) size of pointer:                  8
+
2) sizeof pointer:                  8
6) size of Bit class:               4
+
3) sizeof(Bit) class:               4
7) size of array of 10 int:         40
+
4) sizeof(int[10]) array of 10 int: 40
8) size of array of 10 int (2):     40
+
5) sizeof a        array of 10 int: 40
9) length of array of 10 int:       10
+
6) length of array of 10 int:       10
A) length of array of 10 int (2):   10
+
7) length of array of 10 int (2):   10
B) size of the Derived:             8
+
8) sizeof the Derived class:       8
C) size of the Derived through Base: 4
+
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
 +
 
 
}}
 
}}
 +
 +
===Defect reports===
 +
{{dr list begin}}
 +
{{dr list item|wg=cwg|dr=1122|std=C++98|before=result type of {{c|sizeof}} ({{lc|std::size_t}}) was circularly defined|after=it is defined in the same way as in C}}
 +
{{dr list item|wg=cwg|dr=1553|std=C++11|before={{tt|sizeof}} could be used with bit-field xvalues|after=prohibited}}
 +
{{dr list end}}
  
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc inc | cpp/language/dsc alignof}}
+
{{dsc inc|cpp/language/dsc alignof}}
{{dsc inc | cpp/language/dsc sizeof...}}
+
{{dsc inc|cpp/language/dsc sizeof...}}
{{dsc see c | c/language/sizeof}}
+
{{dsc inc|cpp/types/dsc numeric_limits}}
 +
{{dsc see c|c/language/sizeof}}
 
{{dsc end}}
 
{{dsc end}}
  
 
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}
 
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}

Latest revision as of 01:28, 14 August 2024

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

Queries size of the object or type.

Used when actual size of the object must be known.

Contents

[edit] Syntax

sizeof( type ) (1)
sizeof expression (2)

Both versions are constant expressions of type std::size_t.

type - a type-id (see type naming)
expression - an expression whose operator precedence is not lower than sizeof (e.g. sizeof a + b is parsed as (sizeof a) + b instead of sizeof (a + b))

[edit] Explanation

1) Yields the size in bytes of the object representation of type.
2) Yields the size in bytes of the object representation of the type of expression, if that expression is evaluated.

[edit] Notes

Depending on the computer architecture, a byte may consist of 8 or more bits, the exact number being recorded in CHAR_BIT.

The following sizeof expressions always evaluate to 1:

  • sizeof(char)
  • sizeof(signed char)
  • sizeof(unsigned char)
(since C++17)
  • sizeof(char8_t)
(since C++20)

sizeof cannot be used with function types, incomplete types, or bit-field lvalues(until C++11)glvalues(since C++11).

When applied to a reference type, the result is the size of the referenced type.

When applied to a class type, the result is the number of bytes occupied by a complete object of that class, including any additional padding required to place such object in an array. The number of bytes occupied by a potentially-overlapping subobject may be less than the size of that object.

The result of sizeof is always nonzero, even if applied to an empty class type.

When applied to an expression, sizeof does not evaluate the expression (i.e. the expression is an unevaluated operand)(since C++11), and even if the expression designates a polymorphic object, the result is the size of the static type of the expression. Lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversions are not performed. Temporary materialization, however, is (formally) performed for prvalue arguments: the program is ill-formed if the argument is not destructible.(since C++17)

[edit] Keywords

sizeof

[edit] Example

The example output corresponds to a system with 64-bit pointers and 32-bit int (a.k.a. LP64 or 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
}

Possible output:

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

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
CWG 1122 C++98 result type of sizeof (std::size_t) was circularly defined it is defined in the same way as in C
CWG 1553 C++11 sizeof could be used with bit-field xvalues prohibited

[edit] See also

alignof operator(C++11) queries alignment requirements of a type[edit]
sizeof... operator(C++11) queries the number of elements in a parameter pack[edit]
provides an interface to query properties of all fundamental numeric types
(class template) [edit]
C documentation for sizeof