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)
short
must be at least 16 bits.int
must be at least 16 bits.long
must be at least 32 bits.long long
must 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
long
variables 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.