Is ref in RUST more similar to C++ pointer, rather than C++ referene?


#1

I came from C++, and try to understand what Rust reference is. According to my current understanding, I think Rust reference is more close to C++ pointer, is that right?

You can see:
&T can be converted into const T* safely
Trying to modify the value of a binding through a mut ref, you need to write:
let mut a=1;
{
let b = &mut a;
*b = 5;
}
i.e., use * to convert a reference to a value (which is same for pointer in C++).


#2

In Rust, a reference…

  • Must point to something and is implicitly dereferenced on method calls and data member access (like a C++ reference)
  • Can be reassigned and must be explicitly dereferenced with * for value mutation (like a C++ pointer)
  • Must obey ownership and borrowing rules (unlike any form of C++ indirection)

Thus, my answer would be “it’s a bit of both, and then some”.


#3

I think that Rust references are in the middle between C++ pointers and references.

Pointer like traits:

  1. It’s possible to rebind a rust reference
fn main() {
    let mut i32_ref: &i32 = &92;
    eprintln!("i32_ref = {:?}", i32_ref);
    i32_ref = &62;
    eprintln!("i32_ref = {:?}", i32_ref);
}
  1. Explicit deference (*) and borrow (&) operations are required.

Reference like traits:

  1. Never null.

  2. No need for -> operator.

  3. No intrinsic numerical value.

Unique traits:

  1. ownership and borrowing

  2. sizeof rust reference can be twice that of a pointer (for slices and trait objects)

Probably the closes thing to Rust references in C++ is reference_wrapper?


#4

About the the reference like traits:

No need for -> operator.

I wrote following test code:

struct Ccc{
x:i32,
y:i32
}


fn main() {
    let a=Ccc{x:1,y:2};
    let b=&a;
    println!("{}", (*b).x);//the star can also be omitted.
}

When trying to access a member of a struct through ref, you can write:
b.x
or
(*b).x
Is the underlying mechanism that rust will insert * when one trying to access the member through a ref?


#5

Hah, thanks for pointing out a mistake in my list (now fixed).

Overall, Rust automatically dereferences values as many times as needed until the . operator makes sense. You can learn more about it here.


#6

Forget about comparing references to pointers. It will make you struggle with the borrow checker.

Think of Rust references as read/write locks for objects in memory that give a temporary permission to access something.

In C it’s usual to use lots of pointers for basically anything, but in Rust using many references may get quite cumbersome or not even pass the borrow checker.

In C it’s normal to allocate and return something as a pointer, but in Rust that kind of pointer doesn’t even have a syntax! For example, Box is a pointer, and Rc, String and Vec are used in the same places where you’d use a pointer in C, despite being neither a pointer nor a reference.