views:

116

answers:

5

Why reference types and pointers are same in compiled code?(You can see in third and fourth line). I tried to figure it out but apparently I could not achieve.

If a reference type variable must be initialized at declaration and can not be changed so is there any need to do indirection as in pointers?

int x = 10;

mov dword ptr [x],0Ah

int y = x;

mov eax,dword ptr [x]

mov dword ptr [y],eax

int &i = y;

lea eax,[y]

mov dword ptr [i],eax

int *p = &x;

lea eax,[x]

mov dword ptr [p],eax

p = &i;

mov eax,dword ptr [i]

mov dword ptr [p],eax

x = i;

mov eax,dword ptr [i]

mov ecx,dword ptr [eax]

mov dword ptr [x],ecx

+1  A: 

A reference is represented internally as a pointer. It's the compiler that puts the restriction on initialization and non-reseatability.

If a reference type variable must be initialized at declaration and can not be changed so is there any need to do indirection as in pointers?

The only alternative is copying the value, which is not what a reference does. A reference acts similarly to a pointer: it holds onto the location of an object. The difference is that the reference acts like the object itself, instead of needing to be explicitly dereferenced.

rlbond
can't be just an alias? Lets say 'i' and 'y' can have a same value [in example above].
rekli
@rlbond Actually, the C++ standard requires this behaviour (8.3.2: A reference shall be initialized to refer to a valid objector function.) so a compiler should require it. :)
John Cavan
+2  A: 

If the referece is known by the compiler to always refer to a single particular object/item, then the compiler could certainly optimize away the indirection.

However, most references are in fact bound at runtime. Even if a particular instance of a reference can't be rebound, different executions of a particular scope or different instances of an object that contains reference members may run with the reference bound to a different object for each of those instances. Using indirection is a conventient way for the compiler to deal with this.

The situation where a reference is only ever bound to a single thing might be relatively infrequent enough that compilers might not look for the optimization - especially since it may be that the optimization wouldn't be a noticable gain in most cases.

Also, I suspect you're not turning on compiler optimizations - using your code and calling various functions with y and i and their addresses, a quick test in VC++ 2005 with optimizations on shows that the compiler is not implementing i as a pointer, but as a true alias for y (ie., whenever passing i or &i, the compiler uses the address of y directly).

If you're looking at the debug output of a compiler, it shouldn't surprise you that it always treats a reference as a pointer behind the scenes.

Michael Burr
Sorry, but is there any example for 'However, most references are in fact bound at runtime'?
rekli
@ilker: - examples might be a reference that's an instance member of a class that gets set up by a constructor parameter or a reference that's local to a function.
Michael Burr
+2  A: 

References are nothing but restricted pointers. The only difference is that they must point to an existing variable. You can get around that in C++, but it is much harder to miss with:

int& r = *(reinterpret_cast<int*>(0x0));

Of course this is undefined behavior!

So, basically they are implemented as pointers. They differ in usage in many places, eg. references are derefernced automatically when they come as r-values or l-values:

int x = 0;

int& r = x; // 1) no need to take the address of x like &x

r = r * x; // Manually: (*r) = (*r) * x

They provide a safer alternative to raw-pointers. Also, they come with much more elegant syntax than raw-pointers. Just imagine that you don't have references when overloading class operators.

In summary, they are restricted pointers, with a better/safer aliasing but with reduced functionality.

AraK
References don't necessarily help with aliasing - your example shows `r` and `x` aliasing the same object. The expression `(r++ * ++x)` would have undefined behavior as a result of that aliasing.
Michael Burr
"References are nothing but restricted pointers." That's not true to the standard, it's an implementation detail. By the standard, it's an alias to the object, so it is the object, not a pointer to it. I realize you clarified, but I wanted to note that the first sentance is technically not correct.
John Cavan
@Michael Great observation. In C++ the order of parameters evaluation is not specified. So, references are not special in this case. right?
AraK
@John I know, what you are saying is true but they share the same functionality with pointers, aliasing. Is there something that references can do, pointers cant'? couldn't we consider references functionality a subset of pointers functionality?
AraK
Technically, by the standard they are not the same. A pointer is to an address in memory that contains the object, a reference is an alias (another name) for the object. A couple of big differences come out of that:1. You can't reseat a reference, but you can with a pointer.2. A pointer is an integer (of various sizes depending on the architecture), you can cast it to that. You cannot with a reference (unless, of course, it is a reference to a form of integer but then it casts the value, not the address).3. A pointer can be NULL, a reference cannot.These are big differences.
John Cavan
To finish my thought, since I ran out of room... You could consider just about everything in C++ to be a subset of pointers (with the exception of bitfields). It doesn't mean they are, it just means that with the right code, you can get a pointer to just about anything and that, in general, makes it seem like a subset. In the end, though, the compiler can optimize the behaviour of references by basically handling them like pointers, but you can't.
John Cavan
+1  A: 

The C++ FAQ lite gives a good explanation for what you're seeing: http://www.parashift.com/c++-faq-lite/references.html

Essentially, in a nutshell, the compiler is essentially treating it like a pointer, it uses the address of the object and does the dereferencing work for you.

John Cavan
A: 

yep, references are just syntactic sugar for pointers (with restrictions appropriate for the new syntax). It also lets C++ appear to have copy-by-reference parameter passing, in contrast to C which only has copy-by-value (even pointer parameters)

Gautham Ganapathy