How Are References Implemented Internally

How are references implemented internally?

The natural implementation of a reference is indeed a pointer. However, do not depend on this in your code.

How references are internally stored in c++?

References are just aliases internally the compiler treats them same as pointers.

But for the user from usage perspective there are several subtle differences.

Some of the major differences are:

  • Pointers can be NULL while references cannot.There is nothing called as NULL reference.
  • A const reference extends the lifetime of a temporary bound to it. There's no equivalent with pointers.

In addition, references have some things in common with const pointers (not a pointer to const):

  • References must be initialized at time of creation.
  • A reference is permanently bound to a single storage location, and cannot later be rebound.

When you know you have something(an object) to refer to and you'll never want to refer to anything else use a Reference else use pointers.

C++ How reference works behind the scenes

References in C++ are basically implemented as pointers. I would assume that's how they're implemented in all languages, not just C++.

There's an earlier question with better answers here: How is reference implemented internally?

How a reference in C# is implemented internally?

In current implementations, a reference is just a pointer.

To your program, there is no difference at all between a reference and a pointer, everything that is special about references is handled by the compiler and the garbage collector.

What's relevant to know, really, is that a reference doesn't take up more space than a pointer, and there is no extra step needed to use a reference. A reference is not a pointer to a pointer, or an identity that has to be looked up to get to the actual data.

The .NET memory management doesn't use reference counting, like some other frameworks, so there is no counter that has to be maintained when creating or removing references.

Are C++ references guaranteed to use pointers internally?

If you mean that a reference requires the compiler to allocate storage for a pointer, then that's unspecified.

§ 8.3.2/4


It is unspecified whether or not a reference requires storage.

EDIT: To record Martin Bonner's comment as a useful, practical note,

[F]or debugging purposes it can be quite useful to know what is going on "under the hood". (E.g. to answer questions like "why hasn't this gone completely off the rails?"). In practise, compilers all implement references as pointers (unless they can optimize the reference completely away).

Where does the reference variable gets stored

That is left unspecified, and for good reason. The real answer is: it depends on the reference. It can be represented as a normal pointer, or it may not exist at all.

If you have a function-local reference with automatic storage duration, such as this r:

void foo()
{
int x[4] = {0, 1, 2, 3};
int &r = x[1];
// more code
}

then it will probably not take up any space at all. The compiler will simply treat all uses of r as an alias for x[1], and access that int directly. Notice that such alias-style references can also result from function inlining.

On the other hand, if the reference is "persistent" or visible to other translation units (such as a data member or a global variable), it has to occupy some space and be stored somewhere. In that case, it will most likely be represented as a pointer, and code using it will be compiled to dereference that pointer.

Theoretically, other options would also be possible (such as a lookup table), but I don't think those are used by any real-world compiler.

How references in C++ are implemented with pointers

A reference has the same meaning as a constant pointer.

The code for references and pointers is the same, at least with MSVC2013.

For example:

int u=1,v=3, w;

int& x = u; // initialize reference
w = x; // x is synonym for u;
x++;

int *y = &u; // initalize pointer
w = *y; // y points to u
(*y)++;

The initialisation generates in both case:

lea eax, DWORD PTR _u$[ebp]
mov DWORD PTR _x$[ebp], eax ; of course in the case of the pointe _y$ instead of _x$.

The assignment, in both case generates:

mov eax, DWORD PTR _x$[ebp]
mov ecx, DWORD PTR [eax]
mov DWORD PTR _w$[ebp], ecx

And even the increment generates the same code.

The code generated is the same for whether it is a pointer, a const pointer, or a poitner to const (in the latter case, the ++ does not work). It's the compiler buisness to make sure that const is const.

Now there is a subtle difference in syntax:

int& x = u;         // initialize reference 
int *y = &u; // initalize pointer
int const *z = &u; // initialize pointer to "const int". Pointer itself is not const !
int * const a = &u; // initialize "const pointer" to "int", which is basically a reference.

With these definitions:

//(*z)++;           // invalid because the it points to a const int. 
z = &w; // valid because pointer intself is not const

and:

(*a)++;         // valid because the it points to an int.
// a = &w; // invalid because it's a const pointer

So you could say int& is pretty much equivalent to int * const (I don't use '=' here, because it is reserved to the operator= and looks like a syntax error !)

Of course, with the reference you always use its name as if it was a real variable (ex: x++) while with the const pointer you always have to dereference (aka: (*x)++). So same meaning, but different syntax.

How are weak references implemented?

Not sure I understood your question, but you can have a look at the implementation for the class WeakReference and its superclass Reference in Java. It is well commented and you can see it has a field treated specially by the GC and another one used directly by the VM.



Related Topics



Leave a reply



Submit