I’d like too know what are the exact differences between
*const T and
*mut T types, what guarantees they provide and what invariants the programmer must maintain. i find documentation on the topic a bit thin:
- Non-exhaustive list of “properties to remember” in Rust book: https://doc.rust-lang.org/book/first-edition/raw-pointers.html
- A similar list in the second edition https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html
- A bit of important info about variance in nomicon: https://doc.rust-lang.org/nomicon/subtyping.html
- Nothing in the reference
Here is what I think is true about
*const T and
*mut T. Please correct me if I am wrong and confirm, if I am right.
- It’s not UB to cast between
*const Tis variant and
*mut Tis invariant over T.
- 1) implies that 2) is the single real difference between them.
So if you are using raw pointers to implement a data structure (that is, not for FFI), you can pretty much use any of
*mut, provided that variance is correct. You may even have to use
*const for “mutable” data if you need variance. The prime example of this is a
Unique<T> type, which is logically an owning-raw pointer. It stores
*const T to be variant over T, but give access to
If you are using raw pointers for FFI (as parameter and return types of extern “C” functions), then
*mut is purely a question of documenting intent, and does not affect the generated code at all. However, documenting intent is important, because C and C++ have a rule that you can’t mutate a constant object.