4

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?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Shaurya Chaudhuri
  • 3,772
  • 6
  • 28
  • 58
  • 1
    what's java to do with above question? – SMA Jan 10 '15 at 17:31
  • What are you asking? – juanchopanza Jan 10 '15 at 17:32
  • Read the question, folks. I know what he's asking. – Robert Harvey Jan 10 '15 at 17:32
  • 2
    There is no pass by reference in C. – alk Jan 10 '15 at 17:32
  • The common problems of the context in which a question/answer occurs apply. @RobertHarvey The wider the context the more ambiguities might be revealed. – alk Jan 10 '15 at 17:34
  • @almasshaikh - I just used it as an example others - Was this such a bad question? Like i said it might look like a stupid question. I am not a professional at anything, but i am not a complete noob either. I know how things go, but i feel that there must be something more behind the simplest things as well. – Shaurya Chaudhuri Jan 10 '15 at 17:38
  • 4
    **See the update to the title of the question.** – Robert Harvey Jan 10 '15 at 17:43
  • 1
    `But passing by reference by pointers in C is just passing the pointers by value.` I will give a prize to anyone that can decipher this :) First, the only way to pass parameters in 'C' is by value. It doesn't matter what type the value is, whether it is an int, double, float, *or pointer*. – PaulMcKenzie Jan 10 '15 at 17:49
  • @PaulMcKenzie: If you extend the semantics to the actual objects, you can see how passing around pointers is really reference passing of objects. – Robert Harvey Jan 10 '15 at 18:00
  • Related if not a duplicate: http://stackoverflow.com/q/373419/694576 – alk Jan 10 '15 at 18:28
  • 2
    Many programming terms mean different things depending on context. In particular, "reference" in "pass by reference" doesn't mean the same as "reference" in Java. – molbdnilo Jan 10 '15 at 18:29
  • Related if not a duplicate^2: http://stackoverflow.com/q/2229498/694576 – alk Jan 10 '15 at 18:29
  • @juanchopanza: Look at the title of the question. – Robert Harvey Jan 10 '15 at 18:44
  • @RobertHarvey I can't reconcile that with the text in the question. Nice title though, that would make for an interesting question. – juanchopanza Jan 10 '15 at 18:46
  • 3
    This question downvoted badly which it deserves not. Question is well documented and sows some research effect. – haccks Jan 10 '15 at 19:46

4 Answers4

5

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
}
DevAB
  • 323
  • 1
  • 4
  • 10
4

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.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • Even in the case of C, global optimization may detect something like x = fun(x); is going to update x, so it treats x as an alias, including the case where x is kept in a register. – rcgldr Jan 11 '15 at 04:19
  • @rcgldr yes, under the as-if rule, where compilers are free to generate code so long as-if it behaves the same in observable (under the standard) ways (roughly). A difference here is that the pointer implementation can only exist via as-if, the reference is *really* the alias, the pointer is a *hack* by the compiler. Any artifacts the pointer's existsnce may cause must fit in the cracks of undefined behavior. – Yakk - Adam Nevraumont Jan 11 '15 at 04:21
3

Two main points:

  • There is no call by reference in C.
  • Pass by value and pass by reference are different. They are not same.

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.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
  • That seems to put everything in the right place. You Said it would be wrong to say "pass by reference" as "Pseduo pass by value" and rather should be called pass by reference by value as Robert harvey Mentioned. But wouldnt that also apply to the C Programming Language? since we are actually kind of passing a reference? Or is this completely ones opinion. – Shaurya Chaudhuri Jan 10 '15 at 20:08
  • okay, yea i forgot a pointer variable is different from a reference variable in C++ – Shaurya Chaudhuri Jan 10 '15 at 21:04
  • Okay, i thought a bit more. Generally the value is passed by value, be it int,char or a pointer . And even in an array only the pointer is passed. But in case of Structures in C the pointer isnt passed until we pass it, we can pass for lack of a better word "objects" of structures in C as well like ** void printBook( struct Books book ) **- So though pass by ref doesnt exist in C, we can still pass the reference of a structure object, or is every element of the structure gets copied to a new mem location ??? – Shaurya Chaudhuri Jan 11 '15 at 15:20
  • @ShauryaChaudhuri; That pointer to structure is actually passed by value because address of structure is copied to the function parameter. – haccks Jan 11 '15 at 17:36
  • Yea the pointer is passed by value but i talking about the cases when a structure object is accepted as opposed to a pointer to a structure. **void printBook( struct Books book )** as opposed to **void printBook( struct Books* book )** – Shaurya Chaudhuri Jan 11 '15 at 17:52
  • In case of `void printBook( struct Books book )`, a structure object is copied to `book`. – haccks Jan 11 '15 at 17:55
1

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 &param) {
  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.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • I assume C++ is one of the few languages(The only one i know of) which supports complete call by reference, as a feature which can be applied directly using syntax(Though the same thing might happen in the background after its built.) – Shaurya Chaudhuri Jan 10 '15 at 20:09
  • No Pascal had it, Ada, FORTRAN. In the beginning, it was largely used. Now it is considered as bad to have function with side effects so pass by ref is slightly banned. If you are interested there was also a "call by name"... – Jean-Baptiste Yunès Jan 11 '15 at 06:56