C++ Call by reference - c++

If I have a function which takes a pointer to an integer, and I pass a reference to an integer variable from my main, is this call by value or call by reference? Sample code:
#include <iostream>
using namespace std;
void fun(int *a){
//Code block
}
int main(){
int a = 5;
fun(&a);
return 0;
}
In the above code, is the call to function fun a call by value or call by reference?

Your call is a pass by value, but of type int* not of argument type int. This means that a copy of the pointer is made and passed to the function. You can change the value of what it points to but not of the pointer.
So if your function is like this
void fun(int *a)
{
*a = 10;
}
and you call from main like this
int main() {
int b = 1;
fun(&b);
// now b = 10;
return 0;
}
you could modify the value of b by passing a pointer to it to your function.
The same effect would be if you did the following - which is passing by reference
void fun2(int& a)
{
a = 5;
}
int main()
{
int b = 10;
fun2(b);
// now b = 5;
return 0;
}
Now consider a third function that takes an integer argument by value
void fun3(int a)
{
a = 10;
}
int main()
{
int b = 1;
fun3(b);
// b is still 1 now!
return 0;
}
With pass by value, fun3 changes the copy of the argument passed to it, not the variable b in the scope of main.
Passing by (non-const) reference or pointer allows the modification of the argument that is passed to it. Passing by value or const reference will not allow the argument passed to it to be changed.

You're passing a pointer to a, by value.
Depending on which level of abstraction you are speaking, you could say that you are therefore passing a by pointer, or passing a by "handle". In broader terms, "passing a by reference" would not be strictly incorrect, but it is incorrect in C++ because "reference" means something specific in C++. You have no C++ references in this code.

You are passing by value the address where a is located.
So when in your void called fun you type *a, you're accessing the value of a.
But as I've said, you're passing by value an int pointer to a.

It is call by reference as you are passing reference the address reference to your variable so,
inside function
*a = 100;
changes the value of a in caller function as the content at that address has been changed.
But address is passed by value so
a = NULL;
will not change a, as a still be pointing to same address.

Related

Is function name an address to first instruction of that function in c?

Why is compiler saying that this is not pointer:
#include <stdio.h>
double f(){ return 1.2; }
int main(){
int i=0;
double d =f()[0]; //f() is not pointer? it should be
printf("%i\n",d);
}
error:
subscripted value is neither array nor pointer nor vector
double d =f()[0];
But is I have declared a function pointer, and then used a name of a function, then it will become pointer:
#include <stdio.h>
int op(int (*op)(int,int), int a, int b){ return op(a,b); }
int add(int a, int b){ return a+b; }
int main(){
printf("%i\n",op(add, 1, 2)); //here: add() will magically become pointer, different context
}
So in first case, I wanted to dereference the function, in hope, the name of the funtion is pointer (and so derefencing is permitted). In second example, the function pointer is declared with pointer, so the function add will decay to pointer (compare to printf("%i\n",op(&add,1,2))) will also work. So why is problem with the first one?
For a function f, or callable in general, f() is calling the function and evaluates to the type declared as the functions return type. Functions can decay to pointer to function, similar to arrays, but when you call the function, this doesn't happen:
int foo(int,int){ return 1;}
int main() {
using fptr = int (*)(int,int);
fptr p = foo; // <- function pointer (note: no & needed because it decays to function pointer)
fptr q = &foo; // <- also function pointer
int x = foo(1,2); // <- function call
}
In your examples:
double d =f()[0]; //f() is not pointer? it should be
No, f() is not a pointer. f returns a double.
printf("%i\n",op(add, 1, 2)); //here: add() will magically become pointer, different context
No. add() will not magically become a pointer. add is the function that will automagically decay to function pointer (acutally it isnt that "magic").

Why changes the '&' character the output for these two codes?

First code:
int a = 1;
void func(int* ptr) {
ptr = &a;
}
int main() {
int nvar = 2;
int* pvar = &nvar;
func(pvar);
std::cout << *pvar;
}
//Output: 2
Second code:
int a = 1;
void func(int*& ptr) {
ptr = &a;
}
int main() {
int nvar = 2;
int* pvar = &nvar;
func(pvar);
std::cout << *pvar;
}
//Output: 1
The only difference is the '&' character in the 'func' function. But can someone explain me, what it does in this situation?
I know what it does, but in the second code it is combined with * , and I dont know what this combination means
T& denotes "reference to T".
Now replace T with whatever you like. Eg for pointer to int, T==int* we have int*& which is a reference to a pointer to int.
It is no different to passing non-pointers to functions as references. When ptr is passed by value then func works on a copy, when passed by reference func works on the instance passed in.
The & signifies passing by reference:
The difference between pass-by-reference and pass-by-value is that modifications made to arguments passed in by reference in the called function have effect in the calling function, whereas modifications made to arguments passed in by value in the called function can not affect the calling function. Use pass-by-reference if you want to modify the argument value in the calling function. Otherwise, use pass-by-value to pass arguments.
I think that says it better than I could.

Return address of pointer through function

#include<iostream>
using namespace std;
int teradata=65;
int &pointer(int *p2)
{
p2=&teradata;
return &p2;
}
int main()
{
int a=10;
int *p=&a;
int **p3;
p3=pointer(p);
cout<<p3;
return 0;
}
Actually I am trying to return the address of pointer p2 and store it in pointer p3 which is a pointer to a double. Please help correct this program and tell me the error which I did in this program.
Since a function parameter is basically an initialized local variable, returning its address is unproductive if the variable is an object. The object no longer exists when the function returns, so the address itself is also invalid.
If you actually want the address of the pointer variable that was passed to the function, the function needs to accept a reference to the pointer variable being passed. And, it needs to specify the correct return type, which is a pointer to a pointer.
int **pointer(int *&p2) {
p2=&teradata;
return &p2;
}
Your code should not have compiled, and your compiler should have issued a diagnostic about an invalid conversion.
The operation &p2 returns the address of p2. p2 is a pointer to int. So the function pointer should return int ** and not int &:
int **pointer(int *p2) {
p2=&teradata;
return &p2;
}

Why we have to pass the values instead of the address into a "call by reference" function in C++?

I'm new to C++ and learning call by reference now.
I learned this block of code on my material:
void callByRef(&a, &b);
int main(){
int k = 12;
int m = 4;
callByRef(k, m) //QUESTION HERE
return 0;
}
void callByRef(&a, &b){
a += 3;
b -= 2;
return;
}
So my question is when declaring callByRef, we use the addresses of a and b as the parameters, so when we call callByRef in the main, why we need to pass in (k, m) instead of (&k, &m)?
It's basic, but I just want to get the right picture for my future studying.
Thanks guys!
The operator of &a means the address of variable a, the operator of *a means the content of memory addressed by variable a. Now the function definition is following:
void callByRef(int &a, int &b){
a += 3;
b -= 2;
return;
}
where int &a means that a will be a reference to some variable of type int. Therefore whenever you gong to call the function you need to pass the variable itself rather its address, hence callByRef(a, b) and not callByRef(&a, &b).
The reason of such declaration is following, parameters passed to the function, passed by value, namely the content of the variable literally copied into function variable, therefore any change to it inside the function won't have any effect. For example:
void callByVal(int a, int b){
a += 3;
b -= 2;
return;
}
and having:
x = 5;
y = 10;
calling callByVal(x, y) won't have any effect on x and y. To overcome this, you need to pass parameters either by reference or int &a or as an alternative you can pass pointer and update memory directly:
void callByPtr(int *a, int *b){
*a += 3;
*b -= 2;
return;
}
And now it make sense to pass variables addresses, e.g. callByPtr(&a, &b).
The callByRef() function passes the references as arguments so you don't need to send the explicit reference to the function. Have a read through this to understand a bit better.
Tutorial
You don't pass the value. References in C++ aren't exactly like pointers. Think of them as simply being another name for an object.
Naturally you need to bind that name to an object in order for the reference to refer to it. So for instance when we write int &i = k; we are saying that the variable that is already named k, may be referred to as i. To bind the reference, we need to name the other object. And the name of the object is k, not &k.
The same applies to function parameters and arguments. The function callByRef is specified to operate on two objects it will call a and b. When you call that function, you must name the original objects it will refer to. And the original objects are named k and m, not &k and &m.

C++ how to return and collect an address from a function

What return and variable type would I need to use to catch the return value of the address of a variable passed into a function?
Say:
RETURNTYPE get_address(int num){
return &num;
}
int main(){
int num = 1;
DATATYPE = get_address(num);
return 0;
}
RETURNTYPE and DATATYPE should be int*, but note that it does not make much sense to return a pointer to a function argument.
Function argument exists only for as long as the function is executing. Once the function returns that variable no longer exists and using the address returned is essentially undefined behavior.
If you want address of the variable used as argument at the call site then you don't need the function get_address() at all, just use the & operator:
int main(){
int num = 1;
int* pnum = &num;
return 0;
}
If you have access to C++11, you can use the built-in std::addressof.
You can implement a generic function that returns the address of the parameter as such:
template<typename T>
T* addr(T& param)
{
return (T*)&(char&)param;
}
(this is the C++11 implementation, and it's like this because the unary & can be overloaded)
Note that you must pass the parameter by reference otherwise you're returning the address of a local variable, which can result in undefined behavior.
Or you can simply use &. :)
I just need to verify that the address on num is different inside and outside of the function when passed by value.
You can pass the same parameter by value and by reference:
void compareAddresses(int passedByValue, int& passedByReference)
{
std::cout << &passedByValue << " " << &passedByReference;
}
pointer is variable that holds an address. So you need pointer to int.
int* get_address (int num) {
return &num;
}
int main () {
int num = 1;
int* pointer = get_address(num);
return 0;
}
This above of course won't work because you pass the value by copy, and the variable will be deallocated from the stack and the pointer will be invalidated.
If you need a function you should pass it by reference (this will return the correct pointer address of the variable):
int* get_address (int &num) {
return &num;
}
Though you don't need a function. It's a bit excessive. That works just fine:
int* pointer = &num;
You can't, or rather I should say you shouldn't return the address of local scoped variables, as they no longer exist after the function returns. Therefore, you're getting only garbage.
int num = 1;
int* addr = &num;
In C++11 you can use auto when you don't know the type, but you cannot return auto from a function.
auto num = 1;
auto addr = &num;
The local variable gets destroyed after the function has finished. The function call might get over written by other function calls. You wont get what you want. So you shouldn't return a pointer to the local variable of a function.