3 ms·
This is writing to the register space of some peripheral so no, the compiler knows nothing about that. It is also extremely common for such peripherals to have
by stefan_ 5y ago
This is writing to the register space of some peripheral so no, the compiler knows nothing about that. It is also extremely common for such peripherals to have requirements on the order of writes and otherwise silently discard them. They also have all kinds of side effects and don't behave like normal R/W memory at all (e.g. clearing an interrupt is usually done writing a 1 to a register which will read 0 after).
- db48x 5y agoIf you want that kind of guarantee in a Rust program, you can encode it into the types. It does make the implementation more complex, however, so it is not always worth doing.
- tialaramex 5y agoThe compiler doesn't know what's going on here, but fortunately the programmer does and they can use Rust's type safety to reduce the opportunity for foot guns. Notice how the C code calls readb() with some address it got out of another structure adding to a constant from this file, whereas the Rust has readb() as a function implemented on the structure defining what it can write to. As a result, C code can easily mistakenly readb() something it didn't intend to, while the same mistake in Rust fails to compile. Specifically, when you call that Rust readb() function with a constant like GPIO_SIZE that's not actually a GPIO register, it compares the constant you asked to readb to the size of the GPIO's I/O memory (1 page = 4096 bytes) and check it is smaller - if not the type match fails and your compiler tells you this won't work. No runtime crash, it doesn't compile. If you don't have a constant, you can call a try_readb() function, this time you won't fail to compile if you screw up, but at runtime you get EINVAL instead of crashing.
- geocar 5y ago> fortunately the programmer does and they can use Rust's type safety to reduce the opportunity for foot guns. And what, they just didn’t? This is an ordering bug. You could encode that into types perhaps, but I do not think that would be easy or as valuable as other ways to spend time. > Specifically, when you call that Rust readb() function with a constant like GPIO_SIZE that's not actually a GPIO register, it compares the constant you asked to readb to the size of the GPIO's I/O memory (1 page = 4096 bytes) and check it is smaller - if not the type match fails and your compiler tells you this won't work. No runtime crash, it doesn't compile. I think nearly every c compiler has had the ability to warn on something like this for thirty years. What’s the point? The rust programmer could do things differently but so could the C programmer?
- tialaramex 5y ago> This is an ordering bug. It turns out that it isn't. I discussed in another part of the thread that these registers control interrupt handling between them. Maybe if you fiddle with them while something is bouncing the relevant IO pins up and down, you get a spurious interrupt, but I'm actually not sure which ordering would be least likely to cause that, the correct thing is almost certainly to just not blow up if you eat a spurious interrupt while fiddling with these registers or tell the device you don't want interrupts while fiddling with them, both of which are the same in either driver.
- geocar 5y agoWait wait wait. Are you telling me that writing this code in rust created bugs that weren’t in the C implementation? I thought Rust was supposed to eliminate Memory errors and “foot guns” and other programming mistakes idiots make.