0

Variable introduces the identificator which is associated with the memory section. Now, if we have a reference to that variable, then the identificator of the reference is also associated with the memory section of that variable? I created an image to better explain what I mean;

int variable = 0;
int &rVariable = variable;

Now, after the above code has been executed the result might look like the scheme below? enter image description here

So we can think of reference as being as abstraction based on pointers. Thus, any operation (including taking the address of the reference) will actually be applied on the actual object that is referenced. Compiler may allocate memory for storing the reference. But it's not guaranteed.

  • might look like what? – 101010 Aug 13 '14 at 18:54
  • added link to the image – igorastvorov Aug 13 '14 at 18:55
  • Yes, a reference is just another name - an alias - for the referent. Both the original name and the reference denote the same object. – Igor Tandetnik Aug 13 '14 at 18:56
  • Implementation-defined: However the compiler pleases to do it. – Deduplicator Aug 13 '14 at 18:56
  • okay, thanks to all of you! I've read that compiler may allocate memory to store the reference. If compiler does that, then what does it store there? The variable's address? – igorastvorov Aug 13 '14 at 19:00
  • 3
    More often it's implemented as a pointer, rather than as a "soft link", if you will (and this will certainly be the case when the reference takes up memory). But this question is not only unspecific because it will depend on the implementation, but also _far_ too broad because analysing how any particular compiler works could fill a book. – Lightness Races in Orbit Aug 13 '14 at 19:00
  • @user3596139 The compiler often treats references like pointers-with-value-semantics. So yes, it'd be stored like a pointer. – IdeaHat Aug 13 '14 at 19:01
  • @user3596139 In the memory that the reference itself takes up, the address of the variable being referenced is stored. It's very much like having a pointer. I sometimes think of a reference as simply being a pointer that is automatically dereferenced when I use it. – Logicrat Aug 13 '14 at 19:03
  • So we may say, that it's not guaranteed that a compiler allocates memory for storing the reference. The reference is the abstraction based on the pointer. So, by referencing another variable the reference acts as a pointer "underneath". But taking into consideration that reference is the abstraction based on the pointer, any operation on the reference takes effect on the variable it references, so it's safe to think that reference introduces another identifier that can be associated with the same memory location which IS ALREADY associated with the variable's identificator. – igorastvorov Aug 13 '14 at 19:10

1 Answers1

1

Your question is quite broad and thus hard to answer correctly. In concept a reference is an alias to the object. How a specific compiler implements this concept can vary, especially after optimization. In many cases the implementation essentailly uses a pointer to the object, in which case the reference requires memory and what is stored there is probably just the address of the object.

struct S1{
    int & ri;
    S1(int &i):ri{i}{}
};

In this case I would expect the compiler to need memory in order to hold the reference.

struct S2{
    int i;
    int& ri;
    S2():ri{i}{}
};

In this case the reference may not need memory.

At the end of the day one cannot rely on the way a particular compiler in a particular version handles references.

Whether you think of a reference as an alias or as a pointer which must always point to an object (i.e. never nullptr) and always points to the same object (i.e. const) and is automatically dereferenced in your own understanding of a piece of code is probably not important.

Although one can create a "null reference" like

int *i= nullptr;
int& ri=*i;

this is undefined behavior as explained here: Assigning a reference by dereferencing a NULL pointer

Undefined behavior means anything can happen, it might seem that on your compiler the reference still acts like a null pointer, however here are a few edxamples where the compiler could act quite oddly (and is allowed to with no error or warning)

int i;
//...
if(&i) {} //always true
else { 
    //optimized away 
}

int* i;
//...
if(i){}
else{
    //not optimized away
}

int *i = nullptr;
int& ri = *i;
//...
if(&ri){} //could be assumed always true!
else{
    //could be optimized away !!
}

int *i =nullptr;
*i++; //runtime error, convention says user should have checked for nullness
int& ri = i;
ri++; //probably runtime error, user does not know to check for nullness and may not be able to because of optimization assuming &ri ! nullptr

struct S{
    int i[1001];
};
S* s = nullptr;
S& rs = *s;
if(&rs){ //could be assume always true
    rs.i[1000] = 4; //may not result in runtime error, address could be 0x4000,
        // probably still not valid on a pc, on an embedded processor you could be
        // changing clock speed or something nasty even though you checked for 
        // nullness!!!!   Undefined behavior sucks!
}
Community
  • 1
  • 1
odinthenerd
  • 5,422
  • 1
  • 32
  • 61