14
int x = 10;
int& y = x;

For this, x is allocated as 2/4/8 bytes on the stack and 00...1010 is written to those bytes. What would the memory layout and its contents look like for y?

The Vivandiere
  • 3,059
  • 3
  • 28
  • 50
  • 4
    Never presume it's four bytes. It could be eight. References are, *theoretically*, just a convenience for the programmer. In this case `x` and `y` are the same thing, just different names. In practice, who knows. There might be multiple copies of `10` if the compiler thinks that's helpful. Remember, *variables* never occupy memory space, only the values they represent do. – tadman Jul 20 '15 at 16:01
  • 7
    AFAIK the C++ standard only stipulates that a reference should be an alias to another object and doesn't require it to be implemented in any specific manner, so you shouldn't rely on this. – Borgleader Jul 20 '15 at 16:01
  • 3
    @Borgleader That's true, though they do behave a lot like constant auto-dereferencing pointers – KABoissonneault Jul 20 '15 at 16:03
  • 4
    @KABoissonneault Shhhhhhhhhhhhhhhhhhhhhhhhhhhh :P – Borgleader Jul 20 '15 at 16:04
  • 1
    It depends on the case. In your example, y will probably be considered as an alias of x, leaving no impact on the generated code. But AFAIK, when you pass a function argument by reference, it can be implemented as a pointer. It is very difficult to predict what the compiler will do, as the standard allows a lot of freedom. – johan d Jul 20 '15 at 16:04
  • 2
    it could be that y actually wont be allocated at all, or be allocated as pointer – David Haim Jul 20 '15 at 16:05
  • 2
    You aren't guaranteed that `x` is allocated on the stack, or even exists at all, and even if it is, you aren't guaranteed that 00...1010 is stored in whatever bytes are used. –  Jul 20 '15 at 16:05
  • The compiler is allowed to substitute `x` wherever it sees a `y`, so `y` may not have storage. It could be passed to functions via pointer or not. – Thomas Matthews Jul 20 '15 at 19:33

3 Answers3

28

From the C++11 standard 8.3.2.4 [dcl.ref]

It is unspecified whether or not a reference requires storage

So it may or may not need any storage.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
14

Let me quote http://en.cppreference.com/w/cpp/language/reference:

References are not objects; they do not necessarily occupy storage, although the compiler may allocate storage if it is necessary to implement the desired semantics (e.g. a non-static data member of reference type usually increases the size of the class by the amount necessary to store a memory address)

5

From the perspective of C++ languange, it is not defined.

In practice, compilers usually treat references in absolutely the same way as pointers, even though they have many different properties in C++. It means that the address of the referenced variable is physically stored. Perhaps the only assumption that the compiler can make is that the reference is not null. Despite that, I think that you cannot access the address stored in the reference variable in C++ code without taking a pointer first.

Note that the compiler can often optimize reference variable so that you cannot even say where it is in the assembly. And it can do the same to pointer variables.

stgatilov
  • 5,333
  • 31
  • 54
  • 1
    Don't forget that references can extend lifespans; in these cases, the storage would be for the whole object: { Object& my_object = Object(); // my_object lives for whole block } – Lucretiel Jul 20 '15 at 21:28
  • Are you sure references can extend lifespans beyond a single expression? That looks to me like it would be a dangling reference. – Ryan Pavlik Jul 20 '15 at 22:05
  • @Lucretiel [don't do that](http://stackoverflow.com/questions/13826897/why-not-non-const-reference-to-temporary-objects) – NathanOliver Jul 21 '15 at 00:46
  • @Lucretiel const reference can sometimes extend lifespan of temporary. However, it is weird to think that the reference itself takes this memory chunk: it is still the memory of the object which has not been deleted yet. – stgatilov Jul 21 '15 at 04:34
  • Sorry, I meant *some* references- rvalue and const lvalue references. Doing what I did in the example is *exactly* the same as passing a temporary by const ref or rvalue ref as a function argument. { const Object& val = Object(); ... } is exactly the same as void func(const Object&); ... func(Object()); @NathanOliver Yeah, I understand why it's weird, but it's not any different than an rvalue reference- a non-const object is having its lifetime extended to that of the reference. – Lucretiel Jul 21 '15 at 15:47
  • @Adrian removed the offending comment. not sure what I was thinking when I wrote that. – NathanOliver Oct 02 '15 at 13:30