-1

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?

Shepmaster
  • 326,504
  • 69
  • 892
  • 1,159
Basil Ajith
  • 115
  • 9

1 Answers1

9

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:

  • can be initialised unset
  • can be re-bound
  • have their own identity (size, position in memory, …)
  • can be nested
  • can be dereferenced
  • can be put into other things

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

Masklinn
  • 23,560
  • 2
  • 21
  • 39
  • @tadman true, I've rewritten point 1 to try and be less misleading, and make the difference between `&t` and `T&` clearer, does that look better? – Masklinn Oct 02 '20 at 07:37
  • 2
    There's a formatting specifier and trait explicitly for pointers: `println!("{:p}", &food);` will do the trick without having to cast to a raw pointer. The same works for other kinds of pointers, such as `Arc` and `Box`. – trent Oct 02 '20 at 07:41
  • @trentcl true I'd completely forgotten that one, replaced the bits about casting with & and a doc link, thanks. – Masklinn Oct 02 '20 at 07:45