Comment by jcranmer
3 years ago
In addition to what other people have said, I do want to make this point: Rust (more specifically the unsafe core) probably works slightly better as a "portable assembler" than C does. For example:
* Rust doesn't have volatile variables, you use volatile intrinsics on the loads and stores.
* C declares that arithmetic on 'char' and 'short'-sized variables gets promoted to 'int'; Rust actually has proper u8/u16 arithmetic support.
* Rust supports something akin to multiple return values via tuples, which means you can actually get operations like checked-overflow arithmetic supported in the core language, unlike C.
Rust's Wrapping integer types even behave the way "integers" natively work in your CPU rather than, as most programmers want and most languages try somewhat to deliver, behaving like the integers you learned in school on that infinite number line.
Even though this looks like it must surely be some frightfully complicated object-oriented nightmare, Rust's types only exist at compile time, so at runtime (my illustration was constant, but with real variables) this would just to be a 32-bit register doing normal CPU stuff. The optimiser is like "Yeah, Wrapping is how the CPU works anyway" and gets on with it.
Now, on one hand, this seems like a very clumsy thing to write. But then on the other hand, did you actually want CPU-style wrapping integers? No? Then the ones you actually did want are easy to work with in Rust, but don't kid yourself you wanted a "high level assembler" if you can't even handle modulo arithmetic.