Quick question: Is my belief about call by reference/value true?

Started by
38 comments, last by the_edd 14 years, 5 months ago
1. there are no differences between java and c++ regarding the definitions of the terms "call by reference/value". 2. call by value = the stuff that is in the memory location of my variable which is getting passed to a function as a parameter is getting copied into a new memory location. This temporary memory location is pointed to by the function parameter. In case of java objects, this "stuff" is a reference. That way a reference is getting copied (by value though^^) and passed to a function, and still is called "call by value". call by reference = the value of the pointer/reference to the variable which is getting passed on, is getting copied, and that is stored in the function parameter.
Advertisement
1. The terms call by reference mean the same thing for any language, its a computer science concept, not a language feature.

2. From wikipedia:

In call-by-reference evaluation, a function receives an implicit reference to the argument, rather than a copy of its value. This typically means that the function can modify the argument- something that will be seen by its caller.

Call-by-value evaluation is the most common evaluation strategy, used in languages as different as C and Scheme. In call-by-value, the argument expression is evaluated, and the resulting value is bound to the corresponding variable in the function (frequently by copying the value into a new memory region). If the function or procedure is able to assign values to its parameters, only its local copy is assigned — that is, anything passed into a function call is unchanged in the caller's scope when the function returns.
Pretty true. Passing by pointer or by reference is pretty similar on low-level, but syntax wise passing by reference is more convenient.

As a general rule, I pass basic types (int, float, ...) by value (it'll only get slower if you'd pass by reference). Dynamic memory by pointer, and a value that is accessed at multiple places also by pointer. Any object is passed around by reference, unless one wants to copy it (by value).

Also pass objects by const reference. Gives you less compiler complains when passing const reference to a normal reference ^^. And gives you better defined code too.
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
What is an "implicit reference"? If the value of the reference is not getting copied, how else could it work?
Quote:
and the resulting value is bound to the corresponding variable in the function (frequently by copying the value into a new memory region)

This is very unspecific, how does that "binding" take place in java and c++? And how does the evaluation take place? And what is the resulting value?

btw, I don't want to make a new thread just for this, but what does this mean:
void set_zero(int (&n)[5]) {}

What difference do the parenthesis around &n make?
If I've understood you, I'd say you've got the right idea about call by reference/value in the two languages.

As far as I understand it (but I'm rusty on Java):
Java only ever uses references, all variables are references. That's why to get call by value you need to create a new variable eg. Foo(new Bar(x)); the default, Foo(x) will effect x as it's a reference to an object.

In C++, variables can be references or copies. Foo(x) could be by reference or by value. It depends on how the function has been defined. Eg is it:

void Foo(Bar x) // value
Void Foo(Bar& x) // reference
Quote:Original post by burnthepc
If I've understood you, I'd say you've got the right idea about call by reference/value in the two languages.

As far as I understand it (but I'm rusty on Java):
Java only ever uses references, all variables are references. That's why to get call by value you need to create a new variable eg. Foo(new Bar(x)); the default, Foo(x) will effect x as it's a reference to an object.

In C++, variables can be references or copies. Foo(x) could be by reference or by value. It depends on how the function has been defined. Eg is it:

void Foo(Bar x) // value
Void Foo(Bar& x) // reference


Not exactly correct. In Java, method arguments are always passed by value. That means passing any primitive type to a method means they will not be modified outside of the method.
However, anything which is not a primitive type (anything derived from Object) only exists in Java as a reference (although that is the correct term, for someone coming from C++ it feels more like a pointer). The reference is of course passed by value and that means the object referenced by it can be modified inside the method but not the reference itself. This means although the state of the passed object can be changed by mutating method calls it is still the same object though.
Good point BitMaster, I forgot about the built-in types. Under the hood in Java it's all value copies. But from a programmers perspective, C++ reference parameters act more like Java's default behaviour (except for built-in types).

edit:
Quote:
btw, I don't want to make a new thread just for this, but what does this mean:

void set_zero(int (&n)[5]) {}


I think that's a reference to an int array. As in:

int n[5] = {0,1,2,3,4};
set_zero(n);

But I could be wrong.


[Edited by - burnthepc on October 27, 2009 4:49:09 AM]
Quote:
Not exactly correct. In Java, method arguments are always passed by value. That means passing any primitive type to a method means they will not be modified outside of the method.

You see, this is where my problems arose at the first place. In plain language (like you just described) this is perfectly correct. However it does not explain the underlying principle at all! What happens for built-in "int" - not Integer!
in Java? If they just get "copied" into the function argument, ..how? Well, the only explanation that makes sense, is that a new memory location for the function argument is created, and the dereferenced value of that "int" is being copied into that location.
My original question, where I was not entirely sure and therefore created the thread:
For an Integer (not "int", and we are in Java right now) a new memory location is also being created. -> for the function argument, that has to reside somewhere, doesn't it? The difference to c++ is now in my understanding, that Java copies the value of the reference of that Integer and replaces it with the temporary new memory location created for the function parameter.
C++ has "call by reference"...it means, ...it means that it copies the value of the pointer aswell?! Where is the difference then?
On one level, creating references + objects for built-in types is pointless.

A memory address is often a 32-bit number (these are the pointers/ references) a built in type such as an int is also often a 32-bit number. So references aren't made for them as it's as easy to copy the value of the int as to copy the memory address of the value.

In Java, the function copies the pointer/reference/address (so technically it's a value copy). The pointer/reference/address points to the object, so it acts like a reference in C++.

Edit: to clear up Integer int
Quote:For an Integer (not "int", and we are in Java right now)


If I remember right, int is a build in type. Integer inherits from object and so is not a built in type. (One reason I don't like Java!)

so Java
void Foo(Integer x) {x = 0; } // will change x (copy of pointer)
Void Foo(int x) { x = 0; } // does nothing (value copy on built in)

In C++
void Foo(int* x) { *x = 0;} // will change x as it's a copy of a pointer
coid Foo(int x) {x = 0;} // does nothing as it's a value copy
Quote:Original post by Meai
What happens for built-in "int" - not Integer!
in Java? If they just get "copied" into the function argument, ..how? Well, the only explanation that makes sense, is that a new memory location for the function argument is created, and the dereferenced value of that "int" is being copied into that location.


That's not quite the case. It's true that the semantics of pass-by-value languages are that function parameters behave as if they were a memory location, but a compiler is free to use registers to store values so long as the semantics are preserved. That means that the work necessary to pass an int parameter may be a copy, but it could also be a simple load instruction, or a register rename, or even nothing at all if some previous operation leaves the right value in the right register. Telling exactly when copies do occur is usually a matter of looking at the output of the compiler.

Call by value vs call by reference is a question of semantics, not implementation machinery.

This topic is closed to new replies.

Advertisement