• Forum
  • Lounge
  • [FAQ] What is call-by-value and call-by-

 
[FAQ] What is call-by-value and call-by-reference? (AKA pass-by-value and pass-by-reference)

Pages: 123
closed account (z05DSL3A)
[FAQ] What is call-by-value and call-by-reference? (AKA pass-by-value and pass-by-reference)

Okay, this seems to cause a lot of confusion even amongst the experienced programmers.

This refers to the way an argument, the entity used when calling a function, is passed to the parameter, the local variable of a function.

call-by-value
This is where arguments are evaluated before the function is entered. The value of the arguments is use to instantiate (create/initialise) the parameter of the function. Changes to the parameter within the called function have no effect on the actual variable use as an argument to call the function.

call-by-reference
This is an argument passing convention where the address of an argument variable is passed to a function, as opposed to passing the value of the argument expression. Changes to the parameter within the called function change the actual variable use as an argument to call the function.

So let’s have a look at an example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

// Here a, b and c are parameters of the function.
void Func(int a, int * b, int & c)
{

}

int main ()
{
    int   x = 0;
    int * y = &x;
    int   z = 0;

    // Here x, y and z are the arguments to 
    // the function call
    Func(x, y, z);

    return 0;
}


Parameter a
This is call-by-value. When you call the function the value of the argument, x in this case, is used to instantiate the parameter a. Any change to the value of a inside the function will not be made to x.

Parameter b
This is the one that gives most people trouble. It is, again, call-by-value. The argument y is evaluated and this value is used to instantiate the parameter b. If you change the value of the parameter b, i.e. make it point to another address, the value of the argument y is not changed.
As parameter b is a pointer that points to the same variable as the argument y does, it can be dereferenced to change that variable.

Parameter c
This is call-by-reference. The address of the argument z is used to make a reference, the parameter c, so that c effectively becomes another name for z within the function. Any changes to c will directly change z.
The confusion didn't come from the syntax. It came from the meaning. The 'computer-interpretation' is obvious enough.

My argument was that "If I pass an object to a function by value, any changes the made to the object in the scope of the function should not be reflected on the original object." In my view, I don't care about the actual argument, but the meaning of what I'm doing.

If I have a function that works on (the data of) an object, I say I'm passing an object to a function, regardless of how. The copy, pointer or reference is just a means for getting an object into the function. That is the meaning of what I'm doing.

The official thing, of course, is that void myFunc(T& t) doesn't have an object as argument. The argument is a reference, which is passed by value. No changes can be made to the reference (but can be made to the object referenced to). In my eyes "passing a reference to a function" has no meaning [even though it does, obviously, to the computer].

Basically, it's the same as this argument:
Person A: "Hey man, I sent you a mail. Can you reply?"
Person B: "What? I didn't receive a mail from you."
Person A: "Yes you did, check your facebook!"
Person B: "Oh you mean a facebook message. Why didn't you say so?"

Person A sees "sent you a mail" as "I sent you information". Person B sees it as "I sent something through a certain medium". Technically, person B is "the most correct", but then again: an autistic child that chair-hops around the room because his mother told him to stay on his chair is also "technically correct", even though he completely missed the point.
I agree with Gaminic. If you argue that passing a pointer is call by value because the pointer can't be changed from within the function, you might as well say that passing a reference is call by value because you can't rebind the reference. If you are passing a pointer, you are passing a reference to an object, and that's what pass-by-reference means.
@hanst99: Actually, that is the case. See the Java topic.
(Summary: 'Java passes everything by value' + 'Every Object in Java is a reference/pointer' --> In my eyes: a contradiction, because passing an Object in Java behaves like a pass-by-reference.)
I remember posting there about the same thing too.
closed account (z05DSL3A)
Gaminic wrote:
The confusion didn't come from the syntax. It came from the meaning.
I know, hence the post (although not specifically aimed at you).

Gaminic wrote:
If I have a function that works on (the data of) an object, I say I'm passing an object to a function, regardless of how. The copy, pointer or reference is just a means for getting an object into the function. That is the meaning of what I'm doing.
Yes, it is a means of getting an object into a function but what is the object? If the parameter is a pointer, then the object you are 'passing into' the function is a pointer and not what it points to.
There is zero semantic difference between

 
void foo(Bar& foobar);


and

 
void foo(Bar* foobar);


There is no difference between passing a pointer and passing a reference because a pointer IS a reference (although a reference isn't necessarily a pointer, most of the time it is anyways).
@Grey Wolf: What is the meaning of passing a reference to an object by value? Are you planning to do something with that reference, or will you be manipulating the object it's referencing?
closed account (z05DSL3A)
hanst99 wrote:
If you argue that passing a pointer is call by value because the pointer can't be changed from within the function, you might as well say that passing a reference is call by value because you can't rebind the reference.

No, what I am saying is that the argument is evaluated (the value is determined) and the value is used to create the parameter. hence pass by value.

A C++ reference is not evaluated hence it is not passed by value.
closed account (z05DSL3A)
Gaminic wrote:
What is the meaning of passing a reference to an object by value?
It has no meaning.
Alas, I agree. While the pointer itself is passed by value, it is the thing at the other end of the pointer that is of interest. As it stands in the literature, it is also pass by reference (or as I worded it, conforming to technical literature, pass by pointer and pass by indirect reference).

http://www.cplusplus.com/forum/general/35312/
We have gone these rounds before (without consensus, and without very rigorous arguments on either side), but as I will not approve any semantically confusing language in the FAQ we have only a few options available to us:

- research (which I will have to resign myself to doing)
- you can take it over my head directly to twicker and have him make a summary decision
- you can reword it to go over it in more detail in order to make it crystal clear that there are two things involved here: the formal argument type itself and the actual argument referenced.

People reading FAQs are typically newer users and are more interested in what happens to their data, not in being a compiler. Nevertheless I think that something going into these depths is warranted in this instance.

I am not a rube in this area of CS, and I think you ought to take my expertise into consideration.
@Grey Wolf: That's my point. Nobody cares about 'the reference of an object'.

In the end, 'the compiler does X' doesn't matter much. It's more about what behavior can be expected. If a language passes everything by value, then I expect this to do nothing:
void someFunc(someClass C) { C.changeSomeMember(); }
In C++, this is true. In Java, it is not. "Its reference is passed by value" is a bogus explanation, unless you're explaining it to a computer. I've never heard the argument "I didn't kill Joe, my knife did!".

[edit]

@Duoas: Nothing I say should be taken into account for the FAQ (I don't imagine it was, but you never know). I'm not trying to say anything beyond "Java lied to me!".
Last edited on
Mwahahaha int& foo(int*& x).
[Edit]: Edited a few times for increased obscurity.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

int& foo(int*& x)
{ x++;
  return *x;
}

int main()
{ int* x=new int[3];
  x[0]=1;
  x[1]=2;
  x[2]=3;
  std::cout << *x <<"\n";
  std::cout << foo(x) <<"\n";
  foo(x)=5;
  std::cout << *x << "\n";
  x--;
  x=&*&*&*x;
  int*&y=x;
  std::cout << *y << "\n";
  y--;
  std::cout <<  *y;
  std::cin >> *y;
  delete[] x;
  return 0;
}
Last edited on
closed account (z05DSL3A)
This quick draft was posted for comment. If the general consensus is that I'm talking out of my hat, then I will remove it. If you have suggestions for improvement...



The trouble, it seems, is in the definition.

If I ask around if a tomato is a fruit or vegetable, I would get different answers based on who responds. A chef, for example would respond "A tomato is definitely a vegetable". Whereas, a botanist would answer "A tomato is most definitely a fruit". Neither of them are right or wrong, it's just that they don't agree on the definition.

Similarly, you could ask around if passing a pointer is pass-by-value. You would get one side of the room saying "it counts as pass-by-value" and the other saying "it counts as pass-by-reference".

If your definition of "pass-by-value" is based on the mechanics of the function call, then passing a pointer is pass-by-value. However, if your definition is based on the notion of side-effects, then passing a pointer is pass-by-reference.
Last edited on
I think making a distinction between int& and int* params is important.

More than a few times I've seen people try to do something like this:

1
2
3
4
void func(int* foo)
{
  foo = new int[10];
}


Because they thought that since foo was an 'int*' it was being passed by reference.
closed account (zwA4jE8b)
what does the *& in int& foo(int*& x) do? Pass a pointer by reference??
closed account (z05DSL3A)
It(the pointer to an int) is passed by reference.
I thought it was "pass-by-" and not "call-by-" so that it could include returning references?
closed account (z05DSL3A)
I believe that call-by- and pass-by- are generally the same, it just a matter of what the focus of the sentence is. i.e. in the example I would say that x is passed by value and a is called by value. (so whether you are talking about the argument or the parameter).
Last edited on
Pages: 123