Reputation: 8777
I wrote a small program:
#include <iostream>
using namespace std;
int raw(int &x) {
cout<<x<<endl;
cout<<&x<<endl;
}
int main () {
int s= 1;
int &z=s;
raw(s);
raw(z);
return 0;
}
The output is(as expected):
1
0x7fff5ed36894
1
0x7fff5ed36894
It works as I expect it to be but I am curious about how this is implemented internally. Is it function overloading or something else or one of the function is a wrapper around the other function to provide user-friendliness or the compiler does casting while on its own?
Upvotes: 3
Views: 153
Reputation: 1626
This is how it looks in assembler:
int s= 1;
002044A8 mov dword ptr [s],1
int &z=s;
002044AF lea eax,[s]
002044B2 mov dword ptr [z],eax
raw(s);
002044B5 lea eax,[s]
002044B8 push eax
002044B9 call raw (020110Eh)
002044BE add esp,4
raw(z);
002044C1 mov eax,dword ptr [z]
002044C4 push eax
002044C5 call raw (020110Eh)
LEA (in lea eax,[s]
) means Load Effective Address so you can see how z
effectively contains a pointer to location of s
.
push instructions that prepare the arguments before the function call clearly show that you get (the same) pointer as an input in both cases.
This is non-optimized code.
Upvotes: 7
Reputation: 129524
When the compiler produces code for your program, when it sees the &
saying that this is a reference, it really produces a pointer variable [or something, in machine code, that resembles a pointer].
So z
as such will hold the address of s
.
When you call raw(s)
, the compiler says "Ah, so the parameter to raw is a reference which means the address of s
". When you do raw(z)
, the compiler says "Ah, we have a reference already, so lets just pass the content of z
", which since you set it to s
earlier, is the same address as s
.
This is exactly as it should be.
Upvotes: 5
Reputation: 14715
Internally this
int s= 1;
int &z=s;
raw(s);
raw(z);
Is optimized to this:
int s = 1;
raw(s);
raw(s);
Because after you do int &z = s;
variable z
will be aliased to s to end end of its lifetime. So basically it will be the same as s.
Upvotes: 3