LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-29-2012, 10:59 AM   #1
Navjot Arora
LQ Newbie
 
Registered: Apr 2012
Location: Bangalore
Distribution: J ARORA
Posts: 22

Rep: Reputation: Disabled
Regarding Reference variables in C++


Hi All,

I know the basics of reference variable in C++ but I want to know how reference variable works internally and why array of reference and reference of reference is not possible(with example)(I tried with many links but that were not very informative.

Can anyone help me in this or any link which is useful/meet my above requirement.

Last edited by Navjot Arora; 04-29-2012 at 11:04 AM.
 
Old 04-29-2012, 12:02 PM   #2
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 852

Rep: Reputation: 389Reputation: 389Reputation: 389Reputation: 389
I believe that references are equivalent to pointers and are also probably internally implemented as such (but this may be implementation-specific).

Code:
int i = 3;
int& ri = i;
cout << i;
is roughly equivalent to
Code:
int i = 3;
int *pi = &i;
cout << (*a);
With two major differences:
1) a reference does not have an equivalent of a null pointer. It must allways reference something.
2) a reference can be only set in initialization and cannot be changed later. In this respect, it is more similar to a const pointer.

array of references and references to references:
The point of a reference is that you
a) create an alias to something that has a long name so you don't have to type it and make the code more readable
b) to pass parameters to functions by their addressess rather than their values either because you want to change the variable in the function or because it is faster to pass a reference than a large object as an argument.

You can't dereference a reference, therefore you can't have a pointer to a reference (=>array) or a reference to a reference
You don't need an address of a reference, because you can't change what it points to anyway. Also I really can't think of any sensible situation where an array of references would be useful or neeeded. If you feel that you need an array of references, then you probably should use pointers instead.
 
Old 04-29-2012, 01:15 PM   #3
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
A reference is semantically equivalent to a *const, but with the * syntactically hidden during use and the const not overridable (as *const is by const_cast)

Quote:
Originally Posted by millgates View Post
You can't dereference a reference
I would describe that as you can't not dereference a reference.
In your example, we can dereference pi with (*pi) or we can use pi without dereferencing it. We can dereference ri by simply using it (ri) but we have no way to use it without dereferencing it (no way to refer to the pointer itself, rather than the thing it points to).

Notice that &ri is the semantic analog of &*pi, not the analog of just pi.
 
Old 04-29-2012, 03:57 PM   #4
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,804

Rep: Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306
let's speak about function calls:
int i
void my_function(i)
will copy i to the stack and my_function will use that copy, the original variable will not be changed and cannot be reached by the func.
int *p
void my_function(p)
will copy the pointer and the function will use the copy. The original variable is still unreachable, but the copied pointer will point to the same location.
int i
void my_function(&i)
the function will take the original variable, therefore any changes on i inside the function will affect the original variable too. So the function will get a reference to the original variable.

Of course you can use not only int, but other types as well. From this point of view there is no any meaning of "reference of reference".
In the example above
int& ri = i;
ri and i will be the same variable (points to the same memory location), so when you change i, ri will also be changed.
 
Old 04-29-2012, 04:10 PM   #5
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 852

Rep: Reputation: 389Reputation: 389Reputation: 389Reputation: 389
Quote:
Originally Posted by johnsfine View Post
I would describe that as you can't not dereference a reference.
In your example, we can dereference pi with (*pi) or we can use pi without dereferencing it. We can dereference ri by simply using it (ri) but we have no way to use it without dereferencing it (no way to refer to the pointer itself, rather than the thing it points to).
Oh. That's what I meant... but I formulated it incorrectly. Thanks for correcting me.
 
Old 04-29-2012, 04:38 PM   #6
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 852

Rep: Reputation: 389Reputation: 389Reputation: 389Reputation: 389
Quote:
Originally Posted by pan64 View Post
void my_function(i)
void my_function(p)
void my_function(&i)
Sorry, this confused me a bit. Are those function prototypes or function calls?

Quote:
Originally Posted by pan64 View Post
From this point of view there is no any meaning of "reference of reference".
Technically, wouldn't a reference to a reference be the same variable again? I mean, it's like creating a hardlink to a hardlink, right?

Code:
void my_function(&i)
This is the reason why I dislike references a little bit (or at least I did when I first saw C++; the pointer syntax

Code:
function (pointer);
function (&value);
makes it explicit and obvious for whoever reads the code that I pass the parameter by its address and that the function will work with my object and not with its copy. In C when I passed an argument to the function by its value, I knew that the function will not have access to it. With references, the function can get the address of my variable even if I don't explicitly pass it to it. Maybe I'm weird or something.
 
Old 04-29-2012, 05:54 PM   #7
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by millgates View Post
Oh. That's what I meant... but I formulated it incorrectly.
I formulated it as "can't not de..."
How many negatives is that !?
But I couldn't think of a clearer way to express it.

"You must dereference a reference" removes a double negative, but loses some shade of the meaning.
 
Old 04-29-2012, 06:32 PM   #8
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by millgates View Post
... obvious for whoever reads the code that I pass the parameter by its address and that the function will work with my object and not with its copy. ... Maybe I'm weird or something.
AFAIR, in C++ they introduced references in order to be able to call

Code:
func(foo);
regardless of whether foo is something or address to that something. I mean all this in the context of polymorphism.

I.e. kind of to abstract out address of something <-> something issue.

For example, you can define a '+' operation for simple numbers (so you want something) and to matrices (so you want address of something - a matrix can be really big, so you better pass its address). With references you can call

Code:
my_add_op(op1, op2);
regardless of whether op1, op2 are matrices or numbers, furthermore, you can also easily define matrix + number operation.
 
Old 04-30-2012, 02:43 AM   #9
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 852

Rep: Reputation: 389Reputation: 389Reputation: 389Reputation: 389
Quote:
Originally Posted by Sergei Steshenko View Post
AFAIR, in C++ they introduced references in order to be able to call

Code:
func(foo);
regardless of whether foo is something or address to that something. I mean all this in the context of polymorphism.

I.e. kind of to abstract out address of something <-> something issue.

For example, you can define a '+' operation for simple numbers (so you want something) and to matrices (so you want address of something - a matrix can be really big, so you better pass its address). With references you can call

Code:
my_add_op(op1, op2);
regardless of whether op1, op2 are matrices or numbers, furthermore, you can also easily define matrix + number operation.

Yes, I understand and totally respect and appreciate that. I know references are there to make my life easier. They allow you to use the same syntax for passing objects as for passing adresses. This can be useful for example with the operators you mentioned. For example, operators like + and - typically return a new object, because you're not allowed to change any of their operands. On the other hand, operators like << += or ++ typically modify their arguments and return a reference to them. So you can write things like

Code:
(object1++)++;

object2 = object3++ + object4;
stream1 << "hello" << 4 << object1 << whatever;
and they'll all work as expected and you don't have to bother yourself with how they are implemented internally. This could also be handled with pointers instead, but I agree that it would not be nearly as elegant as references. What I meant by my previous post, was that code like
Code:
function(object)
makes an impression that the expression in parentheses is an object while in fact it can very well be an address, which might be a bit confusing if you care about the internals.
I guess I just miss the fact that I could just look at the function call and see that the thing in parentheses is not a pointer and doesn't have an '&' in front of it, so I could rest assured that nothing can happen to it in the function. But never mind, references are cool. Don't take my crazy rants too seriously )
 
Old 04-30-2012, 03:25 AM   #10
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by millgates View Post
...
I guess I just miss the fact that I could just look at the function call and see that the thing in parentheses is not a pointer and doesn't have an '&' in front of it, so I could rest assured that nothing can happen to it in the function. But never mind, references are cool. Don't take my crazy rants too seriously )
We are opening a can of worms. References in C++ are actually quite debatable. I.e. in my earlier post I explained the upside, but there are a lot of downsides too.

I think this all stems from the original C++ design decision to make as compatible with "C" as possible.
 
Old 04-30-2012, 08:16 AM   #11
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,804

Rep: Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306
Quote:
Originally Posted by millgates View Post
Sorry, this confused me a bit. Are those function prototypes or function calls?
yes, they were more or less prototypes, but obviously you will know how a function call of that type will look like.


Quote:
Originally Posted by millgates View Post
Technically, wouldn't a reference to a reference be the same variable again? I mean, it's like creating a hardlink to a hardlink, right?
no, reference looks like a pointer, so when you write &i the system will handle the address of the variable i, but this pointer is not stored in any variable (just passed as an argument) and therefore you will not be able to look for the address of it.


Quote:
Originally Posted by millgates View Post
This is the reason why I dislike references a little bit (or at least I did when I first saw C++; the pointer syntax

Code:
function (pointer);
function (&value);
makes it explicit and obvious for whoever reads the code that I pass the parameter by its address and that the function will work with my object and not with its copy. In C when I passed an argument to the function by its value, I knew that the function will not have access to it. With references, the function can get the address of my variable even if I don't explicitly pass it to it. Maybe I'm weird or something.
You should better think:
function (pointer); will pass a variable. writing function(i); is almost the same, just the type of the variable differs. The system will make a copy of that variable and put it into the stack and the function will use that copy. Obviously the copy will contain the same value (and even, if you want to pass a class, a copy of that class will be used created by the copy constructor).
function (&variable); will not put anything on the stack, and also will not pass a value or a pointer as above, but an address of a variable, therefore inside the function you will be able to access the original variable. If you want to pass a class by reference you will not need to use the copy constructor so this solution is much cheaper. You can also take the pointer and pass that pointer and than use the class by that pointer, but using reference is better, it will allow to produce more readable code.

Yes, references are cool

Last edited by pan64; 04-30-2012 at 08:18 AM.
 
Old 04-30-2012, 09:52 AM   #12
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 852

Rep: Reputation: 389Reputation: 389Reputation: 389Reputation: 389
Quote:
Originally Posted by pan64 View Post
no, reference looks like a pointer, so when you write &i the system will handle the address of the variable i, but this pointer is not stored in any variable (just passed as an argument) and therefore you will not be able to look for the address of it.
That's referencing variable i. I meant more like "reference to a refenence"
Code:
int a;
int& ra = a; // now ra is syntactically the same thing as a (a++ will have the same effect as ra++);
// so if there was something like 
(int&)& rra = ra;
// then it would again (transitivity) be syntactically equivalent to a and therefore again be a reference to int.
I agree that the terminology and the usage of '&' are a bit confusing; making a reference to a variable (int &i = foo) vs referencing a variable (foo = &i).

Quote:
Originally Posted by pan64 View Post
function (pointer); will pass a variable. writing function(i); is almost the same, just the type of the variable differs.
That depends on your definition of variable. By variable, I meant the object you are interested in. In contrast with calling by value, passing a pointer means passing an address of the variable that I am interested in. You may of course argue, that the pointer itself is also a variable, but I don't think that is the point of this discussion.

Quote:
Originally Posted by pan64 View Post
function (&variable); will not put anything on the stack, and also will not pass a value or a pointer as above
Seriously? Then how will the function know where to look for the variable? As said above, the reference is a disguised pointer and the pointer will be passed on stack (at least in case of normal, C-style function calling convention on x86).

Code:
int foo(int& a) { return a; }
int a = 4;

int main() {
	foo(a);
	return 0;
}
translates to (sorry for the long code)

Code:
	.file	"main.cpp"
	.text
.globl _Z3fooRi
	.type	_Z3fooRi, @function
_Z3fooRi:
.LFB0:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	movl	%esp, %ebp
	.cfi_offset 5, -8
	.cfi_def_cfa_register 5
	movl	8(%ebp), %eax
	movl	(%eax), %eax
	popl	%ebp
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE0:
	.size	_Z3fooRi, .-_Z3fooRi
.globl a
	.data
	.align 4
	.type	a, @object
	.size	a, 4
a:
	.long	4
	.text
.globl main
	.type	main, @function
main:
.LFB1:
	.cfi_startproc
	pushl	%ebp
	.cfi_def_cfa_offset 8
	movl	%esp, %ebp
	.cfi_offset 5, -8
	.cfi_def_cfa_register 5
	subl	$4, %esp
	movl	$a, (%esp)
	call	_Z3fooRi
	movl	$0, %eax
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE1:
	.size	main, .-main
	.ident	"GCC: (GNU) 4.5.2"
	.section	.note.GNU-stack,"",@progbits

Quote:
Originally Posted by pan64 View Post
[The function] will not pass a value or a pointer as above but an address of a variable
The pointer is the address of the variable (by definition).

Last edited by millgates; 04-30-2012 at 09:56 AM.
 
Old 04-30-2012, 10:06 AM   #13
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by millgates View Post
... By variable, I meant the object you are interested in. In contrast with calling by value, passing a pointer means passing an address of the variable that I am interested in. ...

Actually, this all is moot. I.e. if in "C" you write

Code:
a = b;
what actually happens is

Code:
*(&a) = *(&b);
, i.e. addresses (pointers) are still involved - unless 'a' and 'b' are register variables.

For that matter, functional languages ( http://en.wikipedia.org/wiki/Functional_programming ) make you realize this all quite deeply.

In functional languages variables are not variables, I'd say they are just names you give nodes in AST (Abstract Syntax Tree) representing the expression you are coding piece by piece. And as such in functional languages variables are immutable.
 
Old 04-30-2012, 11:43 AM   #14
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,804

Rep: Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306Reputation: 7306
Quote:
Originally Posted by millgates View Post
Seriously? Then how will the function know where to look for the variable? As said above, the reference is a disguised pointer and the pointer will be passed on stack (at least in case of normal, C-style function calling convention on x86).
Oh yes, seriously there is no other way, but the reference itself is unavailable from the code (just with tricks), so it is not handled as a passed variable.


Quote:
Originally Posted by millgates View Post
You may of course argue, that the pointer itself is also a variable, but I don't think that is the point of this discussion.
Yes, the pointer itself is a variable and when you pass a variable the purpose of that variable is irrelevant.
If you really look into the compiled code the pointer and a simple integer passed quite similarly. When you pass a variable by reference you will see different compiled code (and the pointer to that variable will never be accessible).

I think the confusion between the pointer and reference is caused because they are mixed: both looks like address of something. When using pointer we are saying about the variable containing the address, but using reference means we are working with the address itself and do not take care about any variable or whatever which may hold it.
 
Old 05-02-2012, 12:42 PM   #15
Navjot Arora
LQ Newbie
 
Registered: Apr 2012
Location: Bangalore
Distribution: J ARORA
Posts: 22

Original Poster
Rep: Reputation: Disabled
Hi All,
Still it is little vague to me.Could anyone please explain much simple way and clearer way?
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Latex, Hyperlink to a reference and from reference to where it is used roy1360 Linux - Software 2 03-21-2011 01:37 PM
how to set the variales for serial port smartgupta Solaris / OpenSolaris 0 11-21-2008 03:54 AM
for your reference!! alicehuang General 0 01-25-2006 03:30 AM
need some reference Hamid Moradmand Programming 0 05-17-2004 12:46 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:22 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration