C doesn't have references, only C++, but I suspect the answer will be similar to const* anyway. I don't recall whether writes are allowed from elsewhere though.
If unsafe code forces a write, this is UB, which you might as well call "not allowed" too. Most likely this just means that the readers might not see that update, but all bets are off.
This is correct. Rust's shared references have a strong guarantee that the data is immutable (and exclusive references that the data is not seen by anyone else at the same time)
Oh, I should add that the immutability is logical, not physical in memory. Cell, RefCell, Mutex, etc. can mutate data behind a shared reference, but they force the code to do it with synchronization or atomic access.
For even more clarification: that only applies to references to types that actually contain UnsafeCell, such as &Cell<f32>. &f32 itself is truly immutable as long as it exists; there is no (legal) way to somehow use UnsafeCell to mutate it.
Could you please clarify this a bit? Of course, I didn't dive deep into the code, but AFAIK, the definition of UnsafeCell is simply "hold the value, give the * mut to it on demand" (and other Cell types are safe wrappers around this pointer). Is there anything else underneath?
UnsafeCell gets special treatment by the compiler in being allowed to mutate its internals via a shared reference. Values that don't involve an UnsafeCell can be assumed to never change through a shared reference under any circumstances.
Its #[lang = "unsafe_cell"] attribute is what indicates special treatment. You can search for that in the compiler sources to track down its effect in more detail. This blog post also offered a good overview of lang items: