Compile-time type functions
A value of type int is one object, and sizeof reports the bytes that one object takes up.
Why Programs Need Byte Counts
Every object a program uses occupies some amount of memory. Usually you do not need to think about that amount, but sometimes you must know it exactly. A low-level program that stores data in a fixed-size buffer depends on knowing how many bytes each value takes. So does a piece of code that must lay out data for another system.
The source for this topic describes a built-in tool for exactly this purpose: the sizeof operator. Instead of writing code that calculates an object's size, you ask the language for the answer.
What do you think happens?
Before reading on: what unit do you think sizeof reports its result in? Bytes, elements, characters, or something else?
Reveal answer
Bytes
The result of sizeof is a count of bytes, not a count of elements or characters. It tells you the number of bytes that the object occupies.
What sizeof Measures
The sizeof operator returns the number of bytes in an object.
Two details in that definition matter. First, the unit is the byte. Second, the operator reports what the object occupies in storage, which is a different question from how many items the object holds. A value of type int is one object, and sizeof reports the bytes that one object takes up.
sizeof answers the question how many bytes does this occupy? It does not answer how many elements are there or how many characters are there.
When sizeof Gets Its Value
The chapter this topic belongs to is about compile-time type functions. The result of sizeof describes a type, so the compiler can determine it without running the program. That is the idea behind the word compile-time: the value is settled while the program is being built, not while it executes.
The diagram below traces this path. The source code contains a line that uses sizeof. The compiler evaluates that expression during the build. The resulting constant is then fixed before the program runs.
Two Forms: Type and Object
The source states that sizeof can be applied to a type, such as int, and also to an object. In the type form you place a type name inside the parentheses, as in sizeof(int). The expression then evaluates to the number of bytes in one object of that type. In the object form you give sizeof a variable name instead of a type name.
| Form | Written as | What it asks |
|---|---|---|
| Type form | sizeof(int) | How many bytes does one object of type int occupy? |
| Object form | sizeof(x) | How many bytes does this particular object x occupy? |
The two forms of sizeof answer closely related questions.
The two forms describe the same quantity when the object's type is the type named in the type form. If x is an int, then sizeof(x) and sizeof(int) ask about the same storage.
sizeof(int)uses the type form: the type name sits inside the parentheses.sizeof(x)uses the object form: the variable name sits inside the parentheses.- Because x has type int, both lines ask about the same size.
Reading the constexpr Example
The source example uses the type form. It declares a named constant called szi, of type int, and initializes it with sizeof(int). The source comment describes the meaning of the value: it is the number of bytes in an int. The question to answer is what number szi will hold.
- constexpr marks szi as a constant that is fixed when the program is compiled.
sizeof(int)produces the byte count of an int.- The value stored in szi is the implementation's size of int, not a number you chose.
The keyword constexpr is why this example is useful. sizeof produces a value that can be used directly in a constant declaration like this one. Notice that the example never writes the number of bytes. It asks the language for it.
Before you look at the value of szi, write down the number you expect it to hold. Say what you based your expectation on. Did you assume a particular size for int, or did you reason only from the definition of sizeof? Keep your answer so you can compare it with the trace of this code.
Hints
- Reread the definition: sizeof returns a count of bytes for the named type.
- Ask yourself whether the source gives you a fixed size for int, or only says that the size is determined by the implementation.
Bytes an Object Occupies
sizeof counts each byte that an object occupies. The diagram below shows an object as a row of byte positions. Each position is one byte of that object's storage. The row here has four positions only to make the idea visible. The real number of bytes for a given type is set by the implementation, so do not treat this picture as a fixed size for int.
When you read sizeof(x), the answer is the length of that run. The count is in bytes, so a larger count means the object takes more storage, not that it holds more items.
Mistakes With sizeof Results
Common mistake Hard-coding the number of bytes for int
What it looks likeWriting constexpr int szi = 4; and assuming it describes int everywhere.
Why it failsThe size is determined by the implementation. The same type can have different sizes on different platforms and compilers, so a fixed number may be wrong when the code moves.
Do this insteadWrite constexpr int szi = sizeof(int); and let the language supply the value for the implementation you are using.
Common mistake Reading sizeof as a count of elements
What it looks likeBelieving that sizeof(int) tells you how many integers there are.
Why it failsThe result is a count of bytes, not a count of elements or characters.
Do this insteadRead sizeof(int) as the number of bytes in one int object, and use the unit of bytes when you interpret the number.
Common mistake Treating sizeof as a value computed while the program runs
What it looks likeExpecting the size of an object to change during execution in a way that sizeof must recalculate.
Why it failsThe result describes the type and is determined at compile time, before the program runs.
Do this insteadThink of sizeof as a compile-time answer about storage, and use its result as a known quantity in your code.
Checking Your Prediction
Write a constant that holds the byte count of a variable of type int named count, using the object form. Then compare the result of that constant with the result of sizeof(int) written in the type form. Predict whether the two values will match before you run the code, and explain your reasoning in one sentence.
Hints
- The object form puts a variable name inside the parentheses.
- Think about whether count has the type int.
Key Takeaways
- The sizeof operator returns the number of bytes in an object, so its unit is the byte, not elements or characters.
- sizeof can be applied to a type, as in
sizeof(int), or to an object, as insizeof(x); for an object of type int the two forms describe the same storage. - The result describes the type and is fixed at compile time, which is why it can initialize a constexpr constant such as szi.
- The size is determined by the implementation, so check it with sizeof rather than hard-coding a number.