jhpratt
jhpratt

Reputation: 7120

Are the usize/isize types in Rust guaranteed to always be either 32 or 64 bits?

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

Answers (2)

Francis Gagn&#233;
Francis Gagn&#233;

Reputation: 65937

This is what The Rust Reference has to say about usize:

usize and isize 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

jhpratt
jhpratt

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

Related Questions