I am (basically) trying to determine if a u64 value fits in a usize. In C this is straightforward:
bool fits_in_size_t(uint64_t v)
{
return v <= SIZE_MAX;
}
Whereas in Rust, an explicit cast is required:
pub fn fits_in_usize(v: u64) -> bool {
return v <= usize::max_value() as u64;
}
I am wondering:
Is there a preferred way to avoid the cast, seeing as a cast might also indicate a (potentially unsafe) narrowing conversion as opposed to a (safe) widening conversion?
Could there theoretically be a Rust implementation where a usize is larger than 64 bits? If so, my Rust code would sometimes be incorrect, whereas my C code would always be correct. I could not find a mention of restrictions on usize in Rust's documentation.
Is there a preferred way to avoid the cast, seeing as a cast might also indicate a (potentially unsafe) narrowing conversion as opposed to a (safe) widening conversion?
You could use num_traits::ToPrimitive::to_usize, which returns None if the value does not fit in a usize. (The added checks will be optimized away when compiling for platforms where they are unnecessary.)
use num_traits::ToPrimitive::to_usize;
pub fn fits(v: u64) -> bool {
match v.to_usize() {
Some(v) => v < usize::max_value() / 2,
None => false
}
}
Could there theoretically be a Rust implementation where a usize is larger than 64 bits?
Yes. usize is always the same size as a pointer. Currently Rust only supports 32- and 64-bit platforms, but there's no guarantee this will always be true. Theoretically Rust could be ported to some future platform with 128-bit pointers.