Ready to practice?
Sign up to access interactive coding exercises and track your progress.
Fixed-Width Integers
Use portable integer types like int32_t and std::size_t for predictable behavior.
The problem with variable-size integers
C++ guarantees only minimum sizes for integer types - not exact sizes. This creates portability problems when you assume a specific size.
For example, int must be at least 16 bits, but it's typically 32 bits on modern systems. If you assume int is always 32 bits, your program will misbehave on systems where int is actually 16 bits.
Fixed-width integers
To solve this problem, C++11 introduced fixed-width integers - types guaranteed to have the same size on all architectures. They're defined in the <cstdint> header:
| Type | Size | Range |
|---|---|---|
std::int8_t |
1 byte signed | -128 to 127 |
std::uint8_t |
1 byte unsigned | 0 to 255 |
std::int16_t |
2 bytes signed | -32,768 to 32,767 |
std::uint16_t |
2 bytes unsigned | 0 to 65,535 |
std::int32_t |
4 bytes signed | -2,147,483,648 to 2,147,483,647 |
std::uint32_t |
4 bytes unsigned | 0 to 4,294,967,295 |
std::int64_t |
8 bytes signed | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
std::uint64_t |
8 bytes unsigned | 0 to 18,446,744,073,709,551,615 |
Example:
#include <cstdint>
#include <iostream>
int main()
{
std::int32_t quantity{32767}; // always 32 bits
quantity = quantity + 1; // 32768 always fits
std::cout << quantity << '\n';
return 0;
}
Use fixed-width integer types when you need a guaranteed range.
Warning: 8-bit types behave like characters
Due to a C++ specification quirk, most compilers treat std::int8_t and std::uint8_t identically to signed char and unsigned char. This means 8-bit fixed-width types often behave like character types, not integers:
#include <cstdint>
#include <iostream>
int main()
{
std::int8_t letter{65};
std::cout << letter << '\n'; // prints 'A', not 65!
return 0;
}
The 8-bit fixed-width integer types often behave like characters rather than integers. The 16-bit and larger types don't have this problem.
Best practices for integral types
Given the complexity of integral types, here are the recommended practices:
Use these:
intwhen size doesn't matter (values fit within 16-bit signed integer range)std::int#_twhen storing quantities needing guaranteed rangestd::uint#_tfor bit manipulation or well-defined wrap-around behavior
Avoid these:
shortandlongintegers (use fixed-width types instead)- Unsigned types for quantities (use signed types instead)
- 8-bit fixed-width types (use 16-bit fixed-width types instead)
What is std::size_t?
The sizeof operator returns a value of type std::size_t. This is an alias for an implementation-defined unsigned integral type used to represent byte-sizes or lengths of objects.
#include <cstddef>
#include <iostream>
int main()
{
int number{5};
std::size_t objectSize{sizeof(number)};
std::cout << objectSize << '\n'; // prints 4 on most systems
return 0;
}
std::size_t is guaranteed to be unsigned and at least 16 bits. On 32-bit systems it's typically 32 bits; on 64-bit systems it's typically 64 bits.
If you explicitly use std::size_t, include the <cstddef> header. Using sizeof doesn't require a header.
Fixed-Width Integers - Quiz
Test your understanding of the lesson.
Practice Exercises
Fixed-Width Integer Types
Use fixed-width integer types from <cstdint> to guarantee specific sizes across different platforms.
Lesson Discussion
Share your thoughts and questions
No comments yet. Be the first to share your thoughts!