Reputation: 3842
I know the whole concept of passing by reference in C & C++, and the similar concept of only pass by value in Java. But in a point of view Everything is pass by value isnt it? In C we pass a pointer of the variable to the function. So we are just passing the value of the reference of to the function. And that is the reason we say Java doesnt support pass by reference because we just pass the value of reference variable to the functions. So we pass the reference by value. Though in C++ there is a way of passing by reference since we can pass arguments and the function will work with the same memory location using this format
void swap(int &x, int &y)
But passing by reference by pointers in C is just passing the pointers by value.
void swap(int* x, int* y)
I know the question might seem a bit stupid, but i feel there is a big gaping hole in the whole concept that i have. So what is the actual defination of call by reference, is this just a pseduo name of call by value in another context?
Upvotes: 5
Views: 3942
Reputation: 105992
Two main points:
Pass by value: the called function creates a new set of variables in stack and copies the values of the arguments into them.
Pass by reference: instead of passing values to the function being called, references/pointers to the original variables are passed.
Why do programmers say that “pass by reference” is really “passing references by value?”
In passing references/pointers to the original variables, in fact objects/addresses are passed by value. So, you can say pass by reference is passing reference by value but this doesn't imply that pass by reference is pseudo name of pass by value. The difference between the two is well explained in this answer. I am copying the excerpt:
If I tell you the URL, I'm passing by reference. You can use that URL to see the same web page I can see. If that page is changed, we both see the changes. If you delete the URL, all you're doing is destroying your reference to that page - you're not deleting the actual page itself.
If I print out the page and give you the printout, I'm passing by value. Your page is a disconnected copy of the original. You won't see any subsequent changes, and any changes that you make (e.g. scribbling on your printout) will not show up on the original page. If you destroy the printout, you have actually destroyed your copy of the object - but the original web page remains intact.
Upvotes: 4
Reputation: 36391
You cannot say "pass by reference" is really "passing references by value" without giving a definition of "reference".
In Java, the statement is true (at first approx.) because inside a function you can change the value of a formal parameter that is a reference without changing the value of the parameter passed in the call :
void f(Object param) {
param = null;
}
void g() {
Object o = new Object();
System.out.println(o);
f(o);
System.out.printn(o);
}
Everybody knows that the two print statements will give the exact same results. In fact in Java there is no pass by reference, there is only references that can be passed; and there is only one way to pass arguments : by value.
In C++, this is really different. When you change the value of the reference parameter inside the function, the parameter passed in the call is modified:
void f(int ¶m) {
param = 0;
}
void g() {
int i=12;
cout << i << endl;
f(i);
cout << i << endl;
}
Every C++ programmer knows that the second print will display 0 (while the first is 12).
So in C++, you cannot say that "pass by reference" is "passing references by value". In C++ references have no value, they are just names associated to memory chunks (Standard section 8.3.2 Reference: [ Note: A reference can be thought of as a name of an object. — end note ]). Inside f()
there is only one variable which has two names. Of course, you may object that most of C++ references implementations are hidden pointers, so the statement can be true; but you should be aware that there is many cases where using hidden pointers to implement references can be avoided (Standard section 8.3.2/7 References. It is unspecified whether or not a reference requires storage)... So in C++ the statement is not valid. C++ has really two ways of passing parameters : by value and by reference.
Upvotes: 1
Reputation: 275220
C++ is defined by a standard, modulo bugs. The C++ standard does not specify how references are implemented, nor how they are passed to functions. Nor does it define calling conventions in general, nor does it define pointer layout, the stack, the heap, or a myriad of other implementation details.
Instead it attempts to define what the C++ code means.
References end up being aliases to other values. The most common way to implement them is as a pointer under the hood: but in as there is no way to access that pointer value, nor side effects from accessing through it, this makes it easy for compilers to eliminate the existence of the reference completely, and just use the referred to value directly.
If the complier cannot do this, it will typically pass a pointer or equivalent.
Despite often being implemented as a pointer, it is still different as the semantics of interaction with it are different: they cannot be reseated, they cannot have their address taken, and they cannot be uninitialized (null or equivalent).
Naturally these rules can be broken via undefined behavior.
Upvotes: 4
Reputation: 353
Passing by reference means the called functions' parameter will be the same as the callers' passed argument (not the value, but the identity - the variable itself). Pass by value means the called functions' parameter will be a copy of the callers' passed argument. The value will be the same, but the identity - the variable - is different. Thus changes to a parameter done by the called function in one case changes the argument passed and in the other case just changes the value of the parameter in the called function (which is only a copy).
Simple Example in C++
#include <iostream>
void by_val(int arg) { arg += 2; }
void by_ref(int&arg) { arg += 2; }
int main()
{
int x = 0;
by_val(x); std::cout << x << std::endl; // prints 0
by_ref(x); std::cout << x << std::endl; // prints 2
int y = 0;
by_ref(y); std::cout << y << std::endl; // prints 2
by_val(y); std::cout << y << std::endl; // prints 2
}
Upvotes: 5