Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why core::cmp::Ordering::cmp cast to i32 from for compare?

THe core::cmp::Ordering type has #[repr(u8)], but in cmp method we see the following code:

(*self as i32).cmp(&(*other as i32))

Why is the casting is not to u8?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Why is the casting is not to u8?

The first reason would be that Ordering‘s variants have the values -1, 0, and +1 so it would require an i8 to start with.

And although this was simply a replacement of int to i32, the reason why it’s remained i32 rather than be narrowed to i8 is the standard library integer usage guidelines:

  1. Use unsigned values if the value should always be greater than or equal to zero, and signed values otherwise.
  2. For indices, pointers, or other values which are tied to a data structure whose size is proportional to the size of memory, use usize or isize.
  3. For cases where the acceptable domain of a value perfectly fits a fixed number of bits, use the appropriate fixed-size type. For example, a method like write_u16 would take a u16 argument.
  4. Otherwise, use i32/u32 if the value has a narrow range and i64/u64 otherwise.

The examples specifically notes that this is a case were (3) doesn’t actually apply, not with this example but with a fairly close one:

The radix of an integer would use u32. You might expect u8, since a radix higher than 256 is not useful, but the domain of useful radices is actually much smaller than u8, so using u8 isn’t providing a meaningful guarantee, and will simply increase friction.

The exact same reasoning applies for ordering, it probably could have been an i8 but there was no reason to break the guidelines, and that might have required additional compiler work (as some platforms have only a subset of all operations below 32 bits e.g. ARM). Though one drawback is a possible issue for platforms with 16 bits registers, I don’t know if Rust supports or cares about those much (I know it supports pointers / addresses from 16 bits upwards, less sure for GPRs).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading