rajenpandit
rajenpandit

Reputation: 1361

How an alias for a variable works in C++

As per my knowledge for int a; compiler will allocate a memory segment in stack, for int *p; also compiler will allocate a memory segment in stack but here p can only point to an address of integer variable.

In C++ we have a concept called alias (aka 'reference') like int &x=a; that means x will start working like a.

My question is whether the compiler allocates any separate memory segment for x also or compiler will treat x as a only; I mean will the compiler assign same address for both.

Upvotes: 2

Views: 3341

Answers (3)

A reference is nothing more or less than a pointer in disguise. It is basically a C++ way of omitting adding the dereference operators when dereferencing a pointer.

From a language lawyer perspective, references may not be the same a pointers, but for all practical purposes, they are. Take for instance the assertion that references cannot be null, this is one of the arguments that people have used to advocate the use of references over pointers. However, while the language definition may disallow this, it is very easy to produce a null reference:

int& toReference(int* a) {
    return *a;
}

What happens when you pass a null pointer to toReference()? It will return a null reference. It won't technically dereference the pointer, because toReference() has no interest in the value behind the pointer. To avoid returning a null reference, the compiler would have to specifically insert code to check whether the pointer is null, and abort the program, which would be a waste of CPU time. You get the segfault the moment you try to access the data behind the returned reference, no sooner.


Now, should you use references in your code?
As I said above references are pointers in disguise, and that disguise can be harmful. For instance, if you see a call like the following in C, you can be certain that bar is not modified:

foo(bar);

In C++ you cannot be certain until you have checked whether the function definition contains a &. This is bad. Even worse: imagine you are using a function declared like this:

void foo(int a);

Now, if someone decided, he needed a to be an in/out parameter, and changed the definition into

void foo(int& a);

there would be absolutely no warning that the call foo(bar) would now silently modify the value of bar, i. e. the developer of foo() can break essential assumptions in unrelated places. The only way to avoid such nasty surprises, is to ban the use of non-const references from function arguments. You may use const-references when you want to stick to pass by value semantics and want to avoid the overhead of copying, but use pointers if you intent to modify.

Upvotes: 1

rajenpandit
rajenpandit

Reputation: 1361

I was doing some research on my question, I got answer but it surprised me.

alias.cpp

int main()
{
        int a=5;
        int &x=a;
        int y=a+x;
}

A part of assembly code generated by using g++ -S alias.cpp

alisa.s

subl    $16, %esp
movl    $5, -12(%ebp)        //moving 5 to a
leal    -12(%ebp), %eax      // loading address of a to eax register
movl    %eax, -4(%ebp)       // moving address of a to -4(%ebp) this for x
movl    -4(%ebp), %eax       // moving the value of x that is address of a to eax
movl    (%eax), %edx         // moving the value of the address pointed by eax to edx
movl    -12(%ebp), %eax      // moving the value of a to eax
addl    %edx, %eax           // adding edx and eax

Another file alias2.cpp, here i am using pointer instead of alias.

int main()
{
        int a=5;
        int *x=&a;
        int y=a+*x;
}

the corresponding assembly code, alias2.s

subl    $16, %esp
movl    $5, -12(%ebp)
leal    -12(%ebp), %eax
movl    %eax, -4(%ebp)
movl    -4(%ebp), %eax
movl    (%eax), %edx
movl    -12(%ebp), %eax
addl    %edx, %eax

As we can see the both assembly files generated by two different code blocks are same. that means internally compiler is using the reference variable same as pointer variable, the only difference is the way of managing/writing the code.

Upvotes: 3

c-smile
c-smile

Reputation: 27460

Consider this

void foo(int& a) {
  a = 1;
}

int n = 0;
foo(n);

In order foo to work properly it shall receive address of passed variable. So essentially reference is a pointer to some memory location but with special treatment.

Upvotes: 2

Related Questions