Code in C++
#include <iostream>
#include <string>
using namespace std;
int main() {
string food = "Burger";
cout << &food << endl;
return 0;
}
The same code written in Rust:
fn main() {
let food = "Burger";
prinln!("{}", &food);
}
The output for the C++ program:
0x7fff604b2890
The output for the Rust program:
Burger
Why is this so? What am I missing?
First thing first, in C++ the &
(address-of) operator returns a pointer, that is, given T t;
, &t
will return a T*
.
C++ does have references (T&
), they are not created via the &
operator, I'll point you to this great answer for numerous differences between C pointers and C++ references.
Now to answer your question, the concept of references is completely different between C++ and Rust.
Rust's references are fundamentally smart pointers. If we go down the list from the link above, Rust references:
They're also created using the &
operator, which are all pointer properties.
Now while they're pointers they're not C pointers, they're "smart" because they're (type) safe, and thus like C++ references can't be null
, or dangling. But that makes them safe/sane pointers. Across the board they still really behave as pointers more often than not.
As to what you are missing, the answer is that Display
(the trait used to format things) is blanket-implemented on references by delegating to the parent object, so when you print "a reference" it's going to print whatever is being referred, because... that's way more useful, especially given how common references are in Rust (they're very, very common)[0].
If you want the reference's "pointer value", you can use the pointer value formatting specifier (thanks trentcl):
println!("{:p}", &food);
(you could also cast to a raw pointer which is what I'd originally written but if you just want to print the value that's a lot more work for little payoff).
[0] to be fair other Rust smart pointers behave the same: Box
, Rc
, and friends all delegate Display
to the underlying type