C/C++: sizeof(short), sizeof(int), sizeof(long), sizeof(long long), etc... on a 32-bit machine ve...
Categories:
Understanding sizeof in C/C++: 32-bit vs. 64-bit Architectures

Explore how the sizeof operator for fundamental data types like short, int, long, and long long can vary significantly between 32-bit and 64-bit systems in C and C++.
The sizeof operator in C and C++ is a fundamental tool for determining the memory footprint of data types and variables. While its behavior is often straightforward, understanding how it changes across different system architectures, particularly between 32-bit and 64-bit machines, is crucial for writing portable and efficient code. This article delves into the typical sizes of common integer types (short, int, long, long long) on these architectures and explains the underlying reasons for the variations.
The C/C++ Standard and Integer Sizes
The C and C++ standards do not specify exact sizes in bytes for integer types. Instead, they define minimum ranges and relationships between them. This flexibility allows compilers to optimize for the underlying hardware architecture. The key relationships are:
sizeof(char)is always 1 byte.sizeof(short)<=sizeof(int)<=sizeof(long)<=sizeof(long long)shortmust be at least 16 bits.intmust be at least 16 bits.longmust be at least 32 bits.long longmust be at least 64 bits.
These minimums ensure that types can hold a certain range of values, but the actual sizes are implementation-defined, meaning they depend on the compiler and the target architecture.
flowchart TD
A[C/C++ Standard] --> B{Minimum Size Requirements}
B --> C[short: >= 16 bits]
B --> D[int: >= 16 bits]
B --> E[long: >= 32 bits]
B --> F[long long: >= 64 bits]
F --> G{Implementation Defined Actual Sizes}
G --> H[32-bit Architecture]
G --> I[64-bit Architecture]
H --> J[Compiler Specific Sizes]
I --> K[Compiler Specific Sizes]How C/C++ Standard Defines Integer Type Sizes
Typical Sizes on 32-bit Architectures
On a 32-bit system, the CPU's registers and memory addresses are typically 32 bits wide. Compilers usually align data types to these widths for optimal performance. Here are the common sizes you'd expect:
char: 1 byteshort: 2 bytesint: 4 byteslong: 4 byteslong long: 8 bytes
Notice that int and long are often both 4 bytes on 32-bit systems. This is a common convention, as 4 bytes (32 bits) is the native word size for such architectures, making operations on int and long equally efficient.
#include <iostream>
int main() {
std::cout << "--- 32-bit System (Typical) ---\n";
std::cout << "sizeof(char): " << sizeof(char) << " bytes\n";
std::cout << "sizeof(short): " << sizeof(short) << " bytes\n";
std::cout << "sizeof(int): " << sizeof(int) << " bytes\n";
std::cout << "sizeof(long): " << sizeof(long) << " bytes\n";
std::cout << "sizeof(long long): " << sizeof(long long) << " bytes\n";
return 0;
}
C++ code to demonstrate sizeof on a typical 32-bit system.
Typical Sizes on 64-bit Architectures
On a 64-bit system, the CPU's registers and memory addresses are 64 bits wide. This often leads to long and pointer types expanding to 8 bytes to match the native word size, improving performance for memory addressing and larger integer operations. The common sizes are:
char: 1 byteshort: 2 bytesint: 4 byteslong: 8 byteslong long: 8 bytes
Here, int typically remains 4 bytes, while long expands to 8 bytes. This distinction is important for portability, especially when dealing with system calls or data structures that rely on specific integer widths. The long long type remains 8 bytes, as it already met the 64-bit minimum requirement.
#include <iostream>
int main() {
std::cout << "--- 64-bit System (Typical) ---\n";
std::cout << "sizeof(char): " << sizeof(char) << " bytes\n";
std::cout << "sizeof(short): " << sizeof(short) << " bytes\n";
std::cout << "sizeof(int): " << sizeof(int) << " bytes\n";
std::cout << "sizeof(long): " << sizeof(long) << " bytes\n";
std::cout << "sizeof(long long): " << sizeof(long long) << " bytes\n";
return 0;
}
C++ code to demonstrate sizeof on a typical 64-bit system.
int or long. Instead, use fixed-width integer types from <cstdint> (e.g., int32_t, uint64_t) when specific sizes are critical.Summary of Differences and Implications
The primary difference between 32-bit and 64-bit systems regarding sizeof for fundamental types lies in the long integer type. While int often remains 4 bytes on both, long typically expands from 4 bytes on 32-bit to 8 bytes on 64-bit systems. This change is significant for:
- Memory Usage: Data structures containing many
longvariables will consume more memory on 64-bit systems. - Interoperability: When exchanging data between 32-bit and 64-bit applications (e.g., through files or network sockets), explicit sizing or serialization is necessary to prevent data corruption.
- Pointer Sizes: On 64-bit systems, pointers (
void*,int*, etc.) are also 8 bytes, reflecting the 64-bit address space. This impacts memory alignment and structure padding.
Understanding these differences is vital for debugging subtle issues related to data truncation, buffer overflows, and incorrect memory calculations when porting code or interacting with system-level APIs.

Typical sizeof values for integer types across architectures.