Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do rvalue/const references have memory address and size?

Tags:

c++

reference

I read everywhere that references are not objects, they are just aliases and they have no location on the memory

int x = 256;
int& rx = x;

std::cout << x << " " << &x << std::endl;       // Output: 256  0x15FAB0
std::cout << rx << " " << &rx << std::endl;     // Output: 256  0x15FAB0

// seems legit ... fair enough ...

Now consider the following

const int& r1 = 8;      // lvalue ref to const int
int&& r2 = 32;          // rvlaue ref to int
const int&& r3 = 128;   // rvalue ref to const int

std::cout << r1 << " " << &r1 << std::endl;     // Output: 8     0x15FA8C
std::cout << r2 << " " << &r2 << std::endl;     // Output: 32    0x15FA74
std::cout << r3 << " " << &r3 << std::endl;     // Output: 128   0x15FA5C

// and ...

std::cout << sizeof(r1) << std::endl;   // Ouput: 4
std::cout << sizeof(r2) << std::endl;   // Ouput: 4
std::cout << sizeof(r3) << std::endl;   // Ouput: 4

So why these references behave like objects, they do have values , memory address and size ... are they exception from the rules of references ? are they located on the stack or somewhere else ?

like image 757
Laith Avatar asked Oct 26 '25 10:10

Laith


2 Answers

I guess your real question is "where do the rvalue/const references go when they do not reference anything with a name"?

const int& r1 = 8;      // lvalue ref to const int
int&& r2 = 32;          // rvlaue ref to int
const int&& r3 = 128;   // rvalue ref to const int

In all three situations above the compiler allocates space in a temporary location, places the value there, and gives you a reference to that value. The compiler is allowed to do that because it can guarantee that the temporary location would remain read-only.

That is how your references get their addresses - the objects (8, 32, 128) are still there, because the compiler creates them for you. The addresses of these hidden objects become addresses of the references; the sizes of these hidden objects are reported by the sizeof operator.

like image 132
Sergey Kalinichenko Avatar answered Oct 28 '25 00:10

Sergey Kalinichenko


A sizeof() of a reference does not give you the size of the reference itself, but the sizeof() of whatever the reference is referring to.

struct foo {
    int a[128];
};

foo bar;
foo &baz=bar;

std::cout << sizeof(baz) << std::endl;

You'll get a pretty big sizeof() here. Obviously that's not the size of the reference, but the size of the object being referred to.

This applies to both lvalue and rvalue references.

like image 32
Sam Varshavchik Avatar answered Oct 28 '25 02:10

Sam Varshavchik