pass by reference

A

Arved Sandstrom

Lew said:
When I took a practice certification exam in Java, I was marked wrong for
saying that objects are passed by reference. The fact is that objects are
not passed at all - references are, and they are passed by value.

I think the terminology is bad. I prefer to look at it from a practical
standpoint - can I take the pointer to the Java object (and a pointer it
is), pass it into a method, and make changes to the object pointed to from
within the method, in such a way that those changes are reflected outside
the method? Yes. I may get flunked on a certification exam, but I call that
passing the object by reference.

AHS
 
R

Roedy Green

I may get flunked on a certification exam, but I call that
passing the object by reference.

Language is for communication. If you use a word to mean something
different from everyone else does, you just create chaos when you
speak.
 
A

Andreas Leitgeb

Ah, but the problems arise when people try things precisely like the
example that started this thread. That is, try to write:
val = "New String";

The only reason this doesn't work as they think, is because assignment
is always on the "pointer" and never on the whole Object.

Given a C-style pointer, one can (in C) either change the pointer, or
the pointed-to Object using assignment:
int i=42,j=84,*p=&i; // p is a pointer to i
*p = 43; // now "i" contains 43 (java has no pendant for that)
p = &j; // "i" is not touched, but p points to j now.

C++'s references behave like pointers that always have the
asterisk before them whenever used, thus the former of these
assignments.

Java can only re-assign "pointers", it cannot assign to the
pointed Object.

It isn't really necessary to resort to parameter passing to see the
difference.
By the (fairly universal) very definition of pass by reference,
one would expect this to work.

By the (at least as "very") definition of "reference" alone, one
might expect different behaviour of Java already. No matter if
it is passed or not. Java doesn't really have "references" the
way C++ has. Java's so called "references" really behave mostly
(but not entirely) like C's pointers.

The confusion comes from talking about "references" in Java in the
first place, not from how something is passed to methods.
There is certainly a higher-level view of what's going on. It's just
best to avoid using terms that have precise low-level meanings when
talking about things in terms of that higher-level view.
I do see your point.
To belabor the point. Suppose, I had this:
[ example of a mutable Object that get's passed down
into a function and modified there - as the Object
was "passed by reference", the changes are still
visible in the Object after the method returns]
Is this an example of pass by reference?
From programmer's PoV it is. From JLS's it's not.
If so, does the term retain any
meaning at all any more?
Yes, at the programmer's level.

Btw., even in C++, which I think we agree does support
both by-value and by-ref passing of objects, really
passes on only "addresses by value" for that. Where
is the difference? The difference is in the semantics
of assignment.
 
A

Arved Sandstrom

Roedy Green said:
Language is for communication. If you use a word to mean something
different from everyone else does, you just create chaos when you
speak.

However, I don't think I mean "pass by reference" and "pass by value" as
anything other than the intuitive meanings:

a) pass by value - the method sees a copy of the parameter, whatever that
may be;

b) pass by reference - the method sees an alias to the parameter. If the
method uses the parameter it is using the actual thing referred to.

With objects Java does (b). I don't care if you call it "passing the
reference by value", or "passing a pointer", or whatever. If I do

Some Object so = new SomeObject(...);
makeChangesToFields(so);

then the fields in 'so' are changed outside the method. This is
pass-by-reference behaviour, not pass-by-value behaviour.

For the record I don't like the "swap" example that gets trotted out to
explain that Java is not pass-by-reference (as an example,
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html).
It's disingenuous. If I write the same example using C++ with pointers to
objects, I get the same results...surprise, surprise.

AHS
 
A

Arved Sandstrom

Lew said:
Except that you aren't passing the object at all.

No, but that's the common terminology. If I do pass by reference in C++ I'm
not passing the object either.
As Patricia Shanahan pointed out, thinking about this with the correct
terminology - Java method arguments are passed by value, and they are
either primitives or references - leads to more correct reasoning about
and predictions of program behavior. It's like Copernican astronomy -
it's actually perfectly valid to think of Earth as the center of the
universe, but the math is so much easier if you put it in orbit around the
Sun.

I have absolutely no problem with that. We can get the C++ folks to also
adopt this perspective, since they are also just passing pointers/references
by value.

AHS
 
A

Andreas Leitgeb

Roedy Green said:
Language is for communication. If you use a word to mean something
different from everyone else does, you just create chaos when you
speak.

Arved and me seem to agree that "pass objects by reference"
and "pass references (to objects) by value" are the same.

Those definitions of "by ref" that are quoted here imply
different results, only because they're based on a definition
of "reference" that is not the same as java's references.
 
P

Patricia Shanahan

Andreas said:
Arved and me seem to agree that "pass objects by reference"
and "pass references (to objects) by value" are the same.

How do you deal with null actual arguments? null is a fine value for a
Java reference, but is not an object.

In general, do you consider the value of an expression such as

new SomeClass()

to be an object, rather than a pointer to an object?

Patricia
 
S

Stefan Ram

Patricia Shanahan said:
null is a fine value for a Java reference

-type(d) expression
, but is not an object.

Any non-null reference also is not an object.
In general, do you consider the value of an expression such as
new SomeClass()
to be an object, rather than a pointer to an object?

It is a reference. This is consistent with its type,
which is a »reference type« (not an »object type«).
 
C

Chris Smith

Andreas said:
The only reason this doesn't work as they think, is because assignment
is always on the "pointer" and never on the whole Object.

Right, because the pointer (or null) is what val *is*. That is the
critical point here. The parameter is a reference, not an object. In
order to view this as pass-by-reference, you'd have to look at the
parameter itself as an object; a perspective that's generally in the
ballpark of what's going on, but is ultimately an inadequate model for
understanding the language.
Given a C-style pointer, one can (in C) either change the pointer, or
the pointed-to Object using assignment:
int i=42,j=84,*p=&i; // p is a pointer to i *p = 43; // now "i"
contains 43 (java has no pendant for that) p = &j; // "i" is not
touched, but p points to j now.

Indeed, because p is the pointer, while *p is the object pointed to.
Therefore, when p occurs on the left of an assignment, the pointer is
assigned. When *p does, the object is assigned. It's worth noting now
that C, like Java, has no pass by reference semantics. It is another
language that is entirely pass by value.
It isn't really necessary to resort to parameter passing to see the
difference.

No, it's certainly not necessary. But one you've got down the kinds of
values that a variable may have (primitive or reference), describing
parameter passing incorrectly, in such a way as to imply that variables
contain objects, then muddies the waters again.
By the (at least as "very") definition of "reference" alone, one might
expect different behaviour of Java already. No matter if it is passed or
not. Java doesn't really have "references" the way C++ has.

I'm not sure what C++ has to do with this.

There really isn't a widely used definition of a reference. The word is
used differently by different languages, and it's best to just adopt the
definition from the language in question. C++ means one thing; Java
another; CAML yet another. On the other hand, pass-by-reference is a
concept with a well-understood definition. Namely: the lvalue of the
formal parameter is the same as the lvalue of the actual parameter.
The confusion comes from talking about "references" in Java in the first
place, not from how something is passed to methods.

I don't agree with this. It works perfectly well to talk about
references in Java, and acknowledge that they are passed by value.
[ example of a mutable Object that get's passed down
into a function and modified there

Actually, that's not what happened at all. The function modified global
state (a static field of the class). I'm afraid you missed the point of
the example. I would be shocked if you are willing to call it pass by
reference. And yet it's ultimately the same thing that's going on when
you modify object state via references passed as parameters.
Btw., even in C++, which I think we agree does support both by-value and
by-ref passing of objects, really passes on only "addresses by value"
for that. Where is the difference? The difference is in the semantics
of assignment.

You are confusing the implementation with the language semantics. When
you pass something by reference in C++, the lvalue of the formal
parameter is the same as the lvalue of the actual parameter. In other
words, the formal parameter is just another name for the same object. So
when you assign to the formal parameter, you are assigning to that
object. That is the only thing that C++ tells you, so it's the only
thing you know. Anything else is speculating about the implementation
details of the compiler.

If we want to engage in such speculation: one possible implementation
(the one likely used for calls between separately compiled modules) is
that the compiler translates this into pushing a memory address onto the
stack. Another implementation technique is to arrange the stack such
that in all calls to a function, the object passed by reference is at a
fixed offset from the end of the caller's stack frame and then accessing
it directly where it sits there. Yet another, useful for small objects
and primitives (which are objects in C++ parlance) in inlined functions,
is to arrange so that the object is allocated to a register rather than
memory in the calling procedure, and leaving that register allocated for
that purpose across the procedure call so that there is no memory address
at all.

So long as the implementation is faithful to the semantic model of what's
going on, it is acceptable. The language semantics don't say that a
memory address is passed. There is nothing in the C++ language
specification about inserting pointer dereference operators
automatically, or anything like that. The spec says that the formal
parameter name inside the function denotes the same object as the actual
parameter in the calling context. It's the poorer books on C++ that
insist on describing behavior in terms of implementation.
 
A

Andreas Leitgeb

How do you deal with null actual arguments? null is a fine value for a
Java reference, but is not an object.

It's as if I got an empty jar after asking for "sugar".

I still will not ask for a "jar" just to avoid this "problem"
of not being able to lingually handle this situation.
 
R

Roedy Green

The parameter is a reference, not an object.

In C++, you can copy entire objects or copy a reference to an object
with = or with parameter passing. In Java it is simpler. You can just
pass the reference. To copy an entire object, you must use the clone
method.

In C++, objects is RAM tend to be contiguous. In Java they are just a
collection of pointers to pieces separately stored. Only the
primitives live in the object itself.

The Java way eliminates the plethora of addressing and dereferencing
modes you have in C++. The drawback of java is, an array of complex
real/imaginary pairs in Java is scattered all over RAM, one object per
complex value, plus one to track the references to them. In C++ you
can store it all in one contiguous hunk much more compactly.
 
R

Roedy Green

However, I don't think I mean "pass by reference" and "pass by value" as
anything other than the intuitive meanings:

These terms have an established meaning in Java. They are somewhat
arbitrary, but they do work better than many alternatives. This was
all hashed out long ago in the days of Java 1.0.

I recall getting smacked down myself back then for not respecting the
established meanings.
 
P

Patricia Shanahan

Andreas said:
It's as if I got an empty jar after asking for "sugar".

I still will not ask for a "jar" just to avoid this "problem"
of not being able to lingually handle this situation.

I think the jar analogy breaks down badly here. I would not hand someone
an empty jar if they asked me to pass the jam, even if the jar were
suitable for jam, or even contained jam at some time in the past, and
might contain jam again in the future.

"Pass the jam." asks for the content, even if it has to be contained and
passed in a jar. "Pass an argument of type String." asks for a String
reference, and can in some cases be usefully satisfied by passing a null
reference to String.

The "pass the jam" analogy would work for languages that really do have
call-by-reference. The callee needs the caller's object. In practice, it
will be represented, under the hood, by a pointer, but there has to be a
real object, real jam in the jar.

Patricia
 
A

Andreas Leitgeb

Peter Duniho said:
With objects, Java still does a). The parameter is a variable that
references the object. It's not the object itself. And a copy of that
reference the variable holds is passed. If Java did support
pass-by-reference, and you passed an object reference "by reference", then
reassigning the reference would not change the original object, but rather
would change the variable that was pointing to (referencing) that object.

I dare the bold assumption, that all partitioners in this discussion do
know how java works.

We're only discussing human language here, not Java's features.

a) Does anyone disagree, that "pass an Object by reference" and
"pass the reference to an Object by value" refer to the same
technical feature?

b) Does anyone disagree that "pass a reference by reference" is an
entirely different feature that is not directly supported by
java, but can be effectively mimicked with arrays and/or Holder-
classes?

Would anyone care to point out any difference of the two concepts in
"a)" without mixing it up with the concept in "b)" ?
In C#, you can additionally pass parameters by reference, including references.

This is also "pass ... by reference", but with C#'s meaning of references,
whereas Java's "pass Objects by reference" is based on java's "references".
Therefore "pass by reference" means something different depending on
the language context.
If you insist on saying that passing a reference to an object is "passing
by reference", then what does it mean to pass a reference by reference, as
you can do in C# (and C++ for that matter)?

exactly that: "pass a reference by reference" :)
 
C

Chris Smith

Andreas said:
a) Does anyone disagree, that "pass an Object by reference" and "pass
the reference to an Object by value" refer to the same technical
feature?

Yes, we basically all disagree. This is based on the simple fact that
they are different things. You can't do one of them in Java, whereas you
can do the other.

In C++, a language where you can do both, the difference is in whether
you specify the parameter as `Class &v` or `Class *v`. The first passes
an object by reference, while the second passes a pointer (basically a
reference in Java terminology) by value.
b) Does anyone disagree that "pass a reference by reference" is an
entirely different feature that is not directly supported by java, but
can be effectively mimicked with arrays and/or Holder- classes?

This is a special case of the fact that "pass X by reference" is always
not directly provided by Java, for all values of X. You've plugged "a
reference" for X there, so you have a true statement. It would remain
true no matter what else you substitute for X.
Would anyone care to point out any difference of the two concepts in
"a)" without mixing it up with the concept in "b)" ?

I've been trying. If you don't see what I'm saying, feel free to ask,
but please point out what you disagree with or don't understand.
This is also "pass ... by reference", but with C#'s meaning of
references, whereas Java's "pass Objects by reference" is based on
java's "references". Therefore "pass by reference" means something
different depending on the language context.

Actually, this may be the point of confusion. Pass by reference is a
concept that has a particular meaning, independent of any other use of
the word "reference" in a language. In particular, pass by reference has
nothing to do with references in Java, or C#, or Ocaml, or most other
languages that call something a reference. The two concepts are related
in C++ specifically because the language committee chose to define
references as a generalization of the concept of pass by reference; i.e.,
a reference in C++ is simply another symbol, with a possibly different
scope, that denotes the same object as the symbol it is initialized from.
 
A

Andreas Leitgeb

Lew said:
"Pass by reference" and "pass reference by value" are not the same thing, as
many have pointed out here.

Many respectable participants of this group have indeed pointed
it out, but they have still kept back any *convincing* arguments
they might have to support their positions.
If you want to deliberately misspeak that's fine,
Misspeaking is not my intention.

Claiming that "pass by reference" is a well-defined term
across all languages, while "reference" itself is not,
just fails to convince me.
 
A

Andreas Leitgeb

Patricia Shanahan said:
"Pass the jam." asks for the content, even if it has to be contained and
passed in a jar. "Pass an argument of type String." asks for a String
reference, and can in some cases be usefully satisfied by passing a null
reference to String.

I never questioned the "reference by value" phrase on technical level.

One level up, however, passing a null-ref may be forbidden, and cause a
NullpointerException to be thrown. At this level, we aren't interested
in empty jars ... ahem... "null", so at that level, talking about
reference-passing is just as common as "passing Objects around".
One level up, java looks quite different.
 
P

Patricia Shanahan

Andreas said:
I dare the bold assumption, that all partitioners in this discussion do
know how java works.

We're only discussing human language here, not Java's features.

Somewhat agree. The purpose of human language, in this situation, is to
enable thought about Java's features, and the ability to communicate
understanding of those features from one person to another.

I came to my current position on this subject after viewing many
articles reflecting parameter passing confusion, in this newsgroup and
in comp.lang.java.help. I came to the conclusion that talking about pass
by reference created a not unreasonable expectation of being able to
change the value of a variable, in the sense of changing what object it
references. As far as I can tell, talking about passing a reference by
value, and about variables and expressions being references not objects,
does not lead to any false expectations.

What do you think is the main objective in selecting terminology to
describe Java parameter passing?

Patricia
 
A

Andreas Leitgeb

Lew said:
Yes, so refusing to use the meaning that is specific in that context is
confusing and foolish.

Says the one, who insists on the language-neutral meaning of
"pass by reference", re-minted on java's references, which
aren't really "references" in the context of where "pass by
reference" was coined.
 
P

Patricia Shanahan

Lew said:
Andreas said:
One level up, however, passing a null-ref may be forbidden, and cause
a NullpointerException [sic] to be thrown. At this level, we aren't
interested

Passing a null reference does not cause a NullPointerException.
Dereferencing a null reference does that.

And a null reference behaves exactly the same way regardless of how one
obtained the null reference.

Dereferencing a formal parameter that represents a null reference actual
parameter is equivalent to dereferencing a local variable or field whose
value is currently null. That is part of the power of the "pass a
reference by value" model.

Patricia
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top