Suppose I'm writing some low-level code that uses hardware registers (I am), and I want to have a global variable representing a set of hardware registers using some struct. For example, I want:
This would allow you to localize unsafe clode blocks (making them easier to audit) and even extract them to a separate crate and compile everything else with unsafe not allowed. (In fact, this is basically the equivalent of using extern and linking with C).
Maybe this will be resolved if/when mem::transmute (and other compiler intrinsics) are declared const.
It probably makes sense to relax the "raw pointers cannot be dereferenced" rule a bit (E0396, the error you get for the first version). Of course, we'd have to make sure reading from memory is diagnosed correctly, but that's straightforward.
transmute will likely never be declared const, for the same reason we don't allow casting raw pointers to integers in constants. (Explanation.)
Yeah, I can see why just de-referencing is problematic, and i can see why this rule would then taint &* -- even though it's not actually dereferencing at compile-time, semantically it is. Thanks for the explanation.
Also makes sense.
As you mention it would be nice to have either relax the derferencing rule for operations that are actually casts, or perhaps some special syntax for (unsafely) casting from a raw pointer or usize to a &'static in static variables.
P.S.
I appreciate the links, very helpful for understand the motivations
It presumes that 0x0 is a null-pointer, but in practice, e.g. on embedded ARM, it is often a meaningful pointer (on Cortex-Ms it often points to the first entry of the vector table).
It leaves for runtime something that is already attested to at compile time -- checking pointer validity -- so would be more cumbersome to use in most of the code than the extern equivalent.