ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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.
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
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.
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.
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.
Sorry, this confused me a bit. Are those function prototypes or function calls?
Quote:
Originally Posted by pan64
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.
... 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.
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
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 )
...
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.
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
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
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.
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
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
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;
}
... 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.
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.
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
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.