What is uintptr_t?
uintptr_t is an unsigned integer type defined in the <stdint.h> header of the C standard library. It is designed to be large enough to hold any pointer value. This makes it an essential type for scenarios where pointers need to be manipulated as integers.
This type is guaranteed to be large enough to hold any pointer value, making it an essential tool for portable and platform-independent pointer manipulation.
History
C99 Standard:
- The C99 standard, published in 1999, introduced
stdint.h, which defines fixed-width integer types. - Within
stdint.h, the typesuintptr_tandintptr_twere introduced.uintptris an unsigned integer type capable of holding any integer value.
Why use uintptr_t?
1 Portability:
- Different architectures (e.g., 32-bit vs. 64-bit) have different pointer sizes. Using
uintptr_tensures that your code can handle pointers correctly regardless of the underlying architecture.
Its Size
The size of uintptr_t varies depending on the architecture of the system because it is designed to be able to hold any pointer value.
32-bit Architectures:
- 32-bit x86 (IA-32)
- Size of
uintptr_t: 4 bytes (32 bits) - Pointers on 32-bit x86 architectures are 32 bits, so
uintptr_tis also 32 bits to accommodate this.
- Size of
- ARM (32-bit)
- Size of
uintptr_t: 4 bytes (32 bits) - Similar to x86, pointers are 32 bits in a 32-bit ARM architecture.
- Size of
64-bit Architectures:
- 64-bit x86 (x86_64 or AMD64)
- Size of
uintptr_t: 8 bytes (64 bits) - Pointers on 64-bit x86 architectures are 64 bits, so
uintptr_tis also 64 bits to accommodate this.
- Size of
- ARM (64-bit, ARM64 or AArch64)
- Size of
uintptr_t: 8 bytes (64 bits) - Similar to x86_64, pointers are 64 bits in a 64-bit ARM architecture.
- Size of
Other Architectures:
- 64-bit PowerPC (PPC64)
- Size of
uintptr_t: 8 bytes (64 bits) - Pointers in 64-bit PowerPC architectures are 64 bits, so
uintptr_tfollows suit.
- Size of
- 64-bit SPARC (SPARC64)
- Size of
uintptr_t: 8 bytes (64 bits) - Pointers in 64-bit SPARC architectures are also 64 bits.
- Size of
Summary Table
| Architecture | Size of uintptr_t |
|---|
| 32-bit x86 | 4 bytes (32 bits) |
| 32-bit ARM | 4 bytes (32 bits) |
| 64-bit x86_64 | 8 bytes (64 bits) |
| 64-bit ARM64 | 8 bytes (64 bits) |
| 64-bit PPC64 | 8 bytes (64 bits) |
| 64-bit SPARC64 | 8 bytes (64 bits) |
Explanation:
- The size of
uintptr_tis directly related to the size of pointers on the given architecture. - On 32-bit architectures, pointers are 32 bits long, making
uintptr_t32 bits. - On 64-bit architectures, pointers are 64 bits long, making
uintptr_t64 bits.
Implementation
#define NULL ((void *)0UL)
typedef unsigned long uintptr_t;
typedef long size_t;
Explanation:
uintptr_tis defined asunsigned long.size_tis defined aslong.
Size Determination by Architecture:
The size of unsigned long and long can vary depending on the architecture and the platform-specific implementation.
32-bit Architectures:
- On most 32-bit systems (e.g., 32-bit x86):
unsigned long: 4 bytes (32 bits)long: 4 bytes (32 bits)
Thus, on a 32-bit architecture:
uintptr_t(defined asunsigned long) will be 4 bytes.size_t(defined aslong) will be 4 bytes.
64-bit Architectures:
- On most 64-bit systems (e.g., 64-bit x86_64, 64-bit ARM):
unsigned long: 8 bytes (64 bits)long: 8 bytes (64 bits)
Thus, on a 64-bit architecture:
uintptr_t(defined asunsigned long) will be 8 bytes.size_t(defined aslong) will be 8 bytes.
Summary Table
| Architecture | Size of uintptr_t | Size of size_t |
|---|
| 32-bit | 4 bytes (32 bits) | 4 bytes (32 bits) |
| 64-bit | 8 bytes (64 bits) | 8 bytes (64 bits) |
Why cant we use unsigned int for uintptr_t and size_t:
Because:
32-bit Systems
- On most 32-bit systems:
intis typically 4 bytes (32 bits).longis typically 4 bytes (32 bits).
In this case, both unsigned int and unsigned long would be 4 bytes, so theoretically, using unsigned int for uintptr_t and size_t would work fine.
64-bit Systems
- On most 64-bit systems:
intis typically still 4 bytes (32 bits).longis typically 8 bytes (64 bits).
In this case, unsigned int would be 4 bytes, while unsigned long would be 8 bytes. Since pointers on 64-bit systems are 64 bits, unsigned int would not be able to hold a pointer value correctly. Thus, using unsigned int for uintptr_t and size_t would fail to represent pointer values on 64-bit architectures.
Why unsigned long is Used:
unsigned longis chosen because it typically matches the size of pointers on most architectures:- 32-bit systems:
unsigned longis 4 bytes, matching 32-bit pointers. - 64-bit systems:
unsigned longis 8 bytes, matching 64-bit pointers.
- 32-bit systems:
This ensures that uintptr_t can hold any pointer value, making it safe and portable across different architectures.
Leave a comment
Your email address will not be published. Required fields are marked *


