Why do raw pointers need the const keyword when references don't?

Viewed 258

Please reference the code below, for the line which has been commented out. It cannot be compiled by the Rust compiler, meaning we need to specify the constness like *const i32 explicitly for a raw pointer in Rust. But for a reference that is immutable to its pointee, we don't need to specify the constness explicitly like with a raw pointer. So, why does Rust not use a more symmetrical way to express the same meaning for both references and raw pointers, since the reference is actually a pointer under the hood?

fn main() {
    let x1: &i32;
    let x2: &mut i32;
    // let p1: *i32;  // This line doesn't compile!!!
    let p1: *const i32;  // we need to specify the constness explicitly.
    let p2: *mut i32;
}
1 Answers

Early versions of Rust (pre-1.0) used *T for const raw pointers (with the same syntax as you note does not work today). RFC 0068 renamed *T to *const T, with justification that it is more error-prone to use *T when transcribing type signatures from existing C code:

The current difference in Rust unsafe pointers types with C pointers types is proving to be too error prone to realistically enable these optimizations at a future date. By renaming Rust's unsafe pointers to closely match their C brethren, the likelihood for erroneously transcribing a signature is diminished.

The RFC also notes (as you do) that this introduces an inconsistency in naming between references and raw pointers:

Today's unsafe pointers design is consistent with the borrowed pointers types in Rust, using the mut qualifier for a mutable pointer, and no qualifier for an "immutable" pointer. Renaming the pointers would be divergence from this consistency, and would also introduce a keyword that is not used elsewhere in the language, const.

Related