However, I'm curious whether Rust contains any type that exactly corresponds to “int” in C; or, if not, then what the best source of that type would be.
I know this is obscure and basically doesn't matter for any practical purpose, but I still want to know the answer.
A brief jaunt on Google led me to this thread recommending the libc crate:
However, it seems thatlibc::c_int is just hard-coded to 32-bit integers on all platforms.
Again, I know this is obscure and basically doesn't matter for any practical purpose, but I'm still curious about the answer.
If the operations are faster on a larger type, the optimizer does that. Making locals bigger is irrelevant, and if you're storing them then the lower memory bandwidth usage of smaller types is better too.
(Maybe there's some use for like a uint_fast36_t that doesn't need to be exactly 5 bytes, but for normal power-of-two types the smaller the better.)
I wonder if this is even possible. C does not even specify the size of ìnt. Only that it is 16 bits or greater but less than or equal to size of long (If I recall correctly).
This does not sound right. Typically on 64 bit Linux/Windows etc int types are not pointer size they are 32 bits. Pointers are 64 bits. As far as the C language standard is concerned ´int´ could be 64 bit also, to match the register size available. I always wondered why that is not the case.
I guess the underlying question here is "How can we always be sure to use an integer size in our Rust that is always the size of the C int we happen to be linking to through our FFI?
I'm guessing it's an embedded platform? I don't have much knowledge of them.
"Desktop" OS wise the only ones I can see that used a 16bit int was Win16 (And apparently classic MacOS, but I can't find more sources backing that up)
Although the C standard says that int is supposed to be the native, most efficient type, in practice it often isn't and long is usually the native type. Except on 16-bit platforms it's not because long has to always be at least 32 bits. It's a mess.
It would be nice if the native type was defined in core.
This becomes difficult to define; on AArch64, is the native type the length of the wN registers, or the length of the xN registers? Both are as efficient to work on, but one is 64-bit and the other is 32-bit.
Similar applies in x86-64 land - it's as efficient to work on Exx as Rxx registers, they're just different sizes.
Why 64-bit, and not 32-bit, given that you can as efficiently do arithmetic on 32-bit registers as 64-bit, but it's more efficient to work with 32-bit integers if there's heavy spilling to memory involved?
Because 64 > 32: I want the maximum size. On 64-bit architectures I can add and multiply 64-bit, 32-bit, 16-bit and 8-bit numbers efficiently in registers, and I want the largest one.
Yes, smaller sizes are more efficient sometimes because of lower memory traffic etc but that's a given on all architectures.
Not on all architectures - on some, it's less efficient to do arithmetic on 16-bit numbers, because that's done by using 32-bit numbers and then applying narrowing conversions to remove the unwanted bits. On AArch64 and x86-64, though, there are operations that are "native" on both 32 bit and 64 bit numbers.
Wanting the largest efficient integer size is different to native, as a result; the largest efficient is 64 bit on both of these architectures, but it's no more native than 32 bit.
OK I'd be fine if it's called core::u_largest_efficient.
I think calling it core::unative is good enough though.
The point is that the differences between the performance of arithmetic operations on u16, u32 and u64 are much smaller than between u64 and u128 on these architectures. There are hardware instructions to multiply 64-bit numbers but there aren't hardware instructions to multiply 128-bit numbers.
Philosophically I'm allergic to putting such C style vagueness into core. It's counter to the Rust style "What You See (in the source) Is What You Get". It's counter to the "correctness" (shall we say) of Rust. It would introduce phenomena that the same Rust code behaves differently on different platforms or with different compilers.
Note that 64 bit operations require the rex prefix byte on x64 (though so will using registers 8-15), so using 64 bit can reduce your instruction cache utilization slightly, if you're really splitting hairs.