Reputation: 7120
If I compile a program targeting a 16 bit architecture, will std::mem::size_of::<usize>()
return 2, or is it guaranteed (via a specification, RFC, or otherwise) to always return 4 or 8?
Upvotes: 9
Views: 6627
Reputation: 65937
This is what The Rust Reference has to say about usize
:
usize
andisize
have a size big enough to contain every address on the target platform. For example, on a 32 bit target, this is 4 bytes and on a 64 bit target, this is 8 bytes.
Note that the phrasing doesn't exclude sizes other than 4 bytes or 8 bytes. Indeed, Rust already supports a platform with 16-bit usize
: msp430-none-elf
(the MSP430 is a 16-bit microcontroller).
If you want to perform conditional compilation based on the size of pointers, you can use the target_pointer_width
configuration option. Here's a sample usage from the core
library:
#[cfg(target_pointer_width = "16")]
#[lang = "usize"]
impl usize {
uint_impl! { usize, u16, 16, 65535, "", "", 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
"[0x34, 0x12]", "[0x12, 0x34]",
usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
}
#[cfg(target_pointer_width = "32")]
#[lang = "usize"]
impl usize {
uint_impl! { usize, u32, 32, 4294967295, "", "", 8, "0x10000b3", "0xb301", "0x12345678",
"0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]",
usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
}
#[cfg(target_pointer_width = "64")]
#[lang = "usize"]
impl usize {
uint_impl! { usize, u64, 64, 18446744073709551615, "", "", 12, "0xaa00000000006e1", "0x6e10aa",
"0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
"[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
"[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
}
Upvotes: 16
Reputation: 7120
It appears the answer is currently no, based on rust-lang/rust#1748. The issue regards assumptions about the size of usize
, and is currently open (and implicitly unresolved). All platforms with tier 1 support are currently 32 or 64 bit [ref].
However, rust-lang/rust#49305 assumes pointers to be at least 16 bits. That is not based on any Rust RFC or specification, as it is mentioned that
[the conversion's] infallibility is supported by the C99 standard which (indirectly) requires pointers to be at least 16 bits.
As this pull request was merged in 2018, it seems this is the current (though unofficial) policy is that usize
and isize
can be assumed to be at least 16 bits, which would mean std::mem::size_of::<usize>()
is not guaranteed to return 4 or 8. On the contrary, it seems like it can already return 2, though that seems to be the lower bound.
Upvotes: 8