What actually happens when passing by reference - c++

When I pass a variable by reference like this:
void function(int &r){
//do something
}
int main(){
int a = 100;
function(a);
return 0;
}
What actually happens ? Does r contain the address of an integer variable or something ? How does it find it ?

Reference of your integer a will be passed as argument to your function. Now in your function, if you change the value pointed by r, it will be reflected in a as well.
So if you assign r=2 in your function and print out a in main, you will see that a has the value 2.
Your program has some syntax errors, but I can understand what you wanted to convey.
Edit:
From the user perspective, it's as if you were receiving a value in the function except that modification done to it are visible from the caller. It's also cheaper in terms of performance when passing big objects because no copy is needed.
How it works in practice is that the compiler actually pass a pointer to the function. But since the caller must have a valid object to pass to the function, a reference can't be invalid contrary to a pointer so you don't need to check for NULL values.

Related

Using Bit-wise operators with an Enum and an unsigned char - Results in 0 [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the difference between passing by reference vs. passing by value?
I read that in C arguments are passed by value, but what's is the difference between passing arguments by value (like in C) or by refencence (like C++ - C#)?
What's the difference between a pointer and a reference?
void with_ptr(int *i)
{ *i = 0; }
void with_ref(int &i)
{ i = 0; }
In these cases are modified both value? If yes, why C++ allows to pass arguments by reference? I think it is not clear inside the function that the i value could be modified.
what's is the difference between passing arguments by value or by reference
If you pass by value, changes to the variable will be local to the function, since the value is copied when calling the function. Modifications to reference arguments will propagate to the original value.
What's the difference between a pointer and a reference?
The difference is largely syntactic, as you have seen in your code. Furthermore, a pointer can be reassigned to point to something else (unless it’s declared const), while a reference can’t; instead, assigning to a reference is going to assign to the referenced value.
I think it is not clear inside the function that the i value could be modified.
On the contrary, it’s absolutely clear: the function signature tells you so.
There’s actually a case to be made that it’s not clear outside the function. That’s why original versions of C# for instance mandated that you explicitly annotate any by-reference calling with ref (i.e. f(ref x) instead of plain f(x)). This would be similar to calling a function in C++ using f(&x) to make it clear that a pointer is passed.
But in recent versions of C#, the use of ref for calling was made optional since it didn’t confer enough of an advantage after all.
Consider this:
1) Passing by reference provides more simple element access i instead of *i
2) Generally you cannot pass null reference to a method, but can pass a null pointer
3) You can't change the address of reference, but can change it for a pointer(although, as pointer itself passed by value, this change will be discarded upon function exit)
Hope, this helped a bit
Actually, in the first case, you can't modify the argument. The pointer itself is immutable, you can only modify the value it points to.
If yes, why C++ allows to pass arguments by reference?
Because pointers can very easily be miss-used. References should almost always be prefered. For your case, what if you pass a NULL to with_ptr? You'll get undefined behavior, which is not possible if you use with_ref.
I think it is not clear inside the function that the i value could be modified.
It is very clear. If you see a function that takes a parameter by non-const reference, you can assume it will be changed.
I think that a method can only change an argument's value, if this is passed by reference. If you pass a argument by value in a method, then whatever change you make to its value, this will no be available in the parent method.
As far as I know, I think the reference is safer to use in a sense that it can't be modified (always points to the same thing), and should be initialized if it's a local variable. Pointer, however, can be change to point to somewhere else.
int x = 10;
int &y = x;
int *p = &x;
p++; //Legal if you know what's next
y++; // Increases the value of x. Now x = y = 11;
As my two cents, I think reference variables are mere alternative names for the same memory address by which it was initialized. This also explains pretty nice:
http://www.dgp.toronto.edu/~patrick/csc418/wi2004/notes/PointersVsRef.pdf

My misconception about pass by and return by reference in C++

Pass by reference:
I have learned that when a variables is passed as a reference to a function then instead of copy, the actual data is passed to the function but i think that if it is really the case then we shouldn't be able to access that data again once the program execution returns to main() after the stack frame of that function gets destroyed and leave that reference variable with zero or null value in main() but it is not the case and we can still access it in the main() so i think that in pass by reference, the memory address of that variable is passed to that function reference variable parameter and then we use that memory in that function with another name(reference variable) and when that function gets destroyed then the reference variables get destroyed rather than the actual data.
is my thinking towards this concept is right or am i doing some mistake in understanding this concept ?
Return By Reference
When a variable which is passed as a reference to another function returns back as a reference to main() then is the memory address passed back to main() or what actually is returned ?
I have learned that when a variables is passed as a reference to a function then instead of copy, the actual data is passed to the function
This is wrong. Passing the actual data would mean the value is passed (either by copy or by move). When passing by reference, a reference to the actual data is passed to the function.
so i think that in pass by reference, the memory address of that variable is passed to that function reference variable parameter and then we use that memory in that function with another name(reference variable)
This is right.
When a variable which is passed as a reference to another function returns back as a reference to main() then is the memory address passed back to main() or what actually is returned ?
A reference can be thought of as a memory address, so returning a reference is similar to returning a pointer (memory address).
When returning a reference from a function, you need to be careful that you don't return a reference to a variable that's local to the function, because that variable no longer exists after the function returns, and you are left with a dangling reference that may crash your program when you try to use it.
passed as a reference to a function then instead of copy, the actual data is passed to the function
It is unclear what you mean by "actual" data. A copy is actual data as much as the origianl object is.
References are a form of indirection. The reference variable indirectly refers to the object to which it was bound. An object variable is distinct from other objects, and its value may be copied from another.
if it is really the case then we shouldn't be able to access that data again once the program execution returns to main()
Binding a reference to an object does not make the object or its data disappear. Example:
void foo(int& ref);
int main()
{
int obj;
foo(obj);
// obj still exists here
}
If you bind a reference to an object defined in main, then the object still exists in main regardless of where that reference was bound.
i doing some mistake in understanding this concept ?
Yes. You did not understand yet what a reference is, or at least were not able to describe them correctly.
Your concept of pass by reference is wrong.
Passing a variable to a function by reference means that something else (let's call it a handle) is passed that acts an alias of the original variable. Every operation that can be performed on the handle within the function (e.g. assigning it a value, retrieving its value, calculating its address, calling a member function if it is an object) are referred to the original variable that was passed by the caller. How those affects are achieved depends on the implementation (e.g. the compiler).
The called function, by performing operations on the handle, does not cause the original variable to cease to exist. (Except in some very specific circumstances, which I won't go into).
For example;
#include <iostream>
void foo(int &x)
{
x = 42; // x is the handle I refer to above
}
int main()
{
int y = 16;
std::cout << y << '\n';
foo(y);
std::cout << y << '\n';
}
will print the values 16 and 42, in that order. The assignment x = 42 in foo() has the effect of changing the value of y in main(). The lifetime of y is unaffected, so y continues to exist until the end of main().
That thing I have referred to as a "handle" is more commonly known as a reference.
Similarly, your concept of returning a reference is wrong. Returning a reference gives a handle to the caller, and the caller can then use the returned handle to access (and perform operations on) whatever variable is returned by the function.
Note that, in the above, I have said nothing about passing the address of a variable around. Because the description above focuses on the observable effect of using references, not on how that observable effect is achieved (e.g. by the compiler).
Behind the scenes, your compiler MIGHT implement all of the magic of references by passing the address of the affected variables around (in fact, most modern compilers do). That is one possible implementation approach. But there are, technically, other ways of achieving that effect - the C++ standard does not require the address of variables to be passed around to achieve the behaviours associated with passing them around by reference.

Trying to convert char* to wchar_t* in function. losing string on returning [duplicate]

Is passing pointer argument, pass by value in C++? Since i see that any change to the pointer as such is not reflected outside the method. The changes i do by dereferencing the pointer is reflected though.
In that case, is it acceptable/standard procedure to use pointer to pointer as argument to a function to modify the pointer value as such within a function?
Yes to both.
Pointers are passed by value as anything else. That means the contents of the pointer variable (the address of the object pointed to) is copied. That means that if you change the value of the pointer in the function body, that change will not be reflected in the external pointer that will still point to the old object. But you can change the value of the object pointed to.
If you want to reflect changes made to the pointer to the external pointer (make it point to something else), you need two levels of indirection (pointer to pointer). When calling functions it's done by putting a & before the name of the pointer. It is the standard C way of doing things.
When using C++, using references is preferred to pointer (henceforth also to pointer to pointer).
For the why references should be preferred to pointers, there is several reasons:
references introduce less syntaxic noise than pointers in function body
references keep more informations than pointers, than can be useful for compiler
Drawbacks of references are mostly:
they break the simple pass-by-value rule of C, what makes understanding the behavior of a function regarding of parameters (will they be changed ?) less obvious. You also need function prototype to be sure. But that is not really worse than the multiple pointer levels necessary when using C.
they are not supported by C, that can be a problem when you write code that should work with both C and C++ programs (but that's not the most usual case).
In the specific case of pointer to pointer, the difference is mostly simplicity, but using reference it may also be easy to remove both levels of pointers and pass only one reference instead of a pointer to pointer.
I understand the confusion here. The concepts of "pass by value" and "pass by reference" are not so clear even if they seem to be so.
Bear in mind that the computer does not know these concepts and does not behave according to it.
The computer does not know about the types. Hence it does not make a distinction of pointers and values.
Let me try to explain by and example:
void func1(int x) //copy some value to local variable x (of type int)
{
x = 5; //modify local variable. lost after function call
}
void func2(int *x) //copy some value to local variable x (of type int*)
{
int a;
x = &a; //modify local variable. lost after function call.
}
void func3(int *x) //copy some value to local variable x(of type int*)
{
*x = 10; //x is local but *x is not! change is saved after function call!
}
func1 and func2 are identical. Both modify a local variable. Modification is lost after function is popped off the stack.
func3 has ability to change another memory location (a variable which is not local to the function).
basically, every function call is "call by value". But in the case of a pointer type, we have a way to change the content of a remote address in memory.
Pass by value using Pointers
I'll explain it by example:
void f(int *ptr)
{
cout<<*ptr;
}
int main ()
{
int a=10;
int *aptr=&a;
f(aptr);
return 0;
}
Here, in main function a is an integer variable whose content is 10 and address is 00F8FB04 (assume).
aptr is pointer to integer, that store the address of integer variable a, so aptr content is address of integer variable a that is 00F8FB04. When we pass aptr as the function argument only content of aptr (that is address) are copies to function parameter.
So, ptr will receive the copy of content of aptr (that is address 00F8FB04)
Either a pointer to a pointer, or a reference to a pointer, is what you would use if you wanted to potentially change the pointer itself. To your original question, technically, yes, all parameters are passed by value.
Yes it is, as it is in C.
In that case, is it acceptable/standard procedure to use pointer to pointer as argument to a function to modify the pointer value as such within a function?
In which case? What do you want? You can use real references with the & modifier.
void func(type &ref);

Converting a float to float*

I have QStandardItem* list in my code
QList<QStandardItem*> lst
Now this is acceptable and works
float a = lst[0]->text().toFloat();
However the following does not work
float* a = &(lst[0]->text().toFloat());
I get an intellisense error stating
Expression must be an lvalue or a function designator
I need a pointer here since I am using an external library that requires a reference that looks like this
some_class.add_variable(const std::string& variable_name, float& t);
So if I get a pointer I could simply pass it as *a
Any suggetsions on how I could resolve this issue ?
The right hand side is what's called a temporary. It is an object which will not exist after the end of the current expression. For obvious reasons, you can't take the address of temporaries; after the expression ends you'd have an invalid pointer.
What you could do is this:
float a = lst[0]->text().toFloat();
float* aPtr = &a;
That will safely make a copy of the temporary value (or in C++11, it may move the temporary), and you can then take a reference to your local, non-temporary variable.
Use float a = lst[0]->text().toFloat(); and simply pass it as &a to the library function.
Taking the address of a temporary value returned by a function is not going to work. This value is supposed to be assigned to an lvalue variable.
Why do you want the address of the float instead of the actual value?
You should only be dealing with addresses of, or pointers to values that have been saved somewhere.
Actually, your external function does NOT need an address, it takes a REFERENCE, so you don't need a pointer.
However, if you really need the pointer to a local variable:
float x = something...;
some_function(&x);
will give you what you are after.
Take care: float* a = &(lst[0]->text().toFloat()); will give you undefined behaviour if you refer to a following this statement. This is because the anonymous temporary (the float returned by .tofloat()) will be out of scope after the statement and a will be invalidated; i.e. will not point to anything meaningful.
You should write float a = lst[0]->text().toFloat(), and pass &a to the function. That is, keep a in scope for as long as you need it.

What's the difference between passing argument by value and by reference? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What's the difference between passing by reference vs. passing by value?
I read that in C arguments are passed by value, but what's is the difference between passing arguments by value (like in C) or by refencence (like C++ - C#)?
What's the difference between a pointer and a reference?
void with_ptr(int *i)
{ *i = 0; }
void with_ref(int &i)
{ i = 0; }
In these cases are modified both value? If yes, why C++ allows to pass arguments by reference? I think it is not clear inside the function that the i value could be modified.
what's is the difference between passing arguments by value or by reference
If you pass by value, changes to the variable will be local to the function, since the value is copied when calling the function. Modifications to reference arguments will propagate to the original value.
What's the difference between a pointer and a reference?
The difference is largely syntactic, as you have seen in your code. Furthermore, a pointer can be reassigned to point to something else (unless it’s declared const), while a reference can’t; instead, assigning to a reference is going to assign to the referenced value.
I think it is not clear inside the function that the i value could be modified.
On the contrary, it’s absolutely clear: the function signature tells you so.
There’s actually a case to be made that it’s not clear outside the function. That’s why original versions of C# for instance mandated that you explicitly annotate any by-reference calling with ref (i.e. f(ref x) instead of plain f(x)). This would be similar to calling a function in C++ using f(&x) to make it clear that a pointer is passed.
But in recent versions of C#, the use of ref for calling was made optional since it didn’t confer enough of an advantage after all.
Consider this:
1) Passing by reference provides more simple element access i instead of *i
2) Generally you cannot pass null reference to a method, but can pass a null pointer
3) You can't change the address of reference, but can change it for a pointer(although, as pointer itself passed by value, this change will be discarded upon function exit)
Hope, this helped a bit
Actually, in the first case, you can't modify the argument. The pointer itself is immutable, you can only modify the value it points to.
If yes, why C++ allows to pass arguments by reference?
Because pointers can very easily be miss-used. References should almost always be prefered. For your case, what if you pass a NULL to with_ptr? You'll get undefined behavior, which is not possible if you use with_ref.
I think it is not clear inside the function that the i value could be modified.
It is very clear. If you see a function that takes a parameter by non-const reference, you can assume it will be changed.
I think that a method can only change an argument's value, if this is passed by reference. If you pass a argument by value in a method, then whatever change you make to its value, this will no be available in the parent method.
As far as I know, I think the reference is safer to use in a sense that it can't be modified (always points to the same thing), and should be initialized if it's a local variable. Pointer, however, can be change to point to somewhere else.
int x = 10;
int &y = x;
int *p = &x;
p++; //Legal if you know what's next
y++; // Increases the value of x. Now x = y = 11;
As my two cents, I think reference variables are mere alternative names for the same memory address by which it was initialized. This also explains pretty nice:
http://www.dgp.toronto.edu/~patrick/csc418/wi2004/notes/PointersVsRef.pdf