Topic: Call by reference using * and &
Author: lam@saifr00.cfsat.honeywell.com (Josh Lam)
Date: Mon, 13 Apr 92 21:43:11 GMT Raw View
In C++, call by reference can be accomplished using pointers (like in C) or
by reference (&). Question: What are some advantages of using references
over pointers (or vice versa)
ie the following functions accomplish pretty much the same thing:
void func1(int & i) // using the reference method
{
...
}
and
void func2(int * i) // using pointer method
{
...
}
The couple of advantages (at least from my limited experiences with C++) of
using the reference method over the pointer method are:
1) It provides a cleaner interface into the function, makes it a little
easier to read and to use
2) The programmer does not have to worry about the address of the pointer,
makes it a little easier to program
Thus,
void func1(int & i) // reference method
{
...
i = 100;
...
}
is 'preferred' over
void func2(int * i) // pointer method
{
...
*i = 100;
...
}
What are some other advantages? Is one really often (if not
always) preferred over the other?
I appreciate any comments. If this has already been discussed
in a separate subject, I apologise for repetition.
Thanks!
Josh Lam
Honeywell Inc
@cum-vax.honeywell.com:lam@saifr00.cfsat.honeywell.com
--
Josh Lam
Honeywell Inc
@cum-vax.honeywell.com:lam@saifr00.cfsat.honeywell.com
Author: dougm@cns.caltech.edu (Doug McNought)
Date: Tue, 14 Apr 1992 13:32:16 GMT Raw View
In article <1992Apr13.214311.24013@saifr00.cfsat.honeywell.com> lam@saifr00.cfsat.honeywell.com (Josh Lam) writes:
In C++, call by reference can be accomplished using pointers (like in C) or
by reference (&). Question: What are some advantages of using references
[deleted]
The couple of advantages (at least from my limited experiences with C++) of
using the reference method over the pointer method are:
1) It provides a cleaner interface into the function, makes it a little
easier to read and to use
2) The programmer does not have to worry about the address of the pointer,
makes it a little easier to program
Some people don't like using references for this purpose, since when reading
the code it is not immediately obvious from the form of the function call that
a variable might be changed by the function. With the address passed explicitly
it is clearer that this is a VAR parameter (as we ex-Pascal types say :). It's
a matter of taste--I don't think there are any real efficiency differences
between the two methods.
Thus,
void func1(int & i) // reference method
is 'preferred' over
void func2(int * i) // pointer method
What are some other advantages? Is one really often (if not
always) preferred over the other?
Stroustrup prefers passing an explicit pointer. I am ambivalent on this issue,
since my code (so far) is for myself alone, and, having used Pascal extensively
I am comfortable with the idea of pass-by-reference. Often it is clear from
context that a variable is being changed.
I appreciate any comments. If this has already been discussed
in a separate subject, I apologise for repetition.
regards,
doug
--
<><><><><><><><><><><><><><><>Go Orioles<><><><><><><><><><><><><><><><>
<> Doug McNaught dougm@descartes.caltech.edu <>
<> Help!!! I'm addicted to *Spaceward Ho!* Is there a support group? <>
<><><><><><><><><><><><><><><>Go Orioles<><><><><><><><><><><><><><><><>
Author: davisonj@en.ecn.purdue.edu (John M Davison)
Date: Tue, 14 Apr 92 13:57:17 GMT Raw View
In article <DOUGM.92Apr14053216@bradbury.cns.caltech.edu> dougm@cns.caltech.edu (Doug McNought) writes:
>In article <1992Apr13.214311.24013@saifr00.cfsat.honeywell.com> lam@saifr00.cfsat.honeywell.com (Josh Lam) writes:
> In C++, call by reference can be [faked] using pointers (like in C) or
> by reference (&). Question: What are some advantages of using references
>Some people don't like using references for [deleted] purpose, since when
>reading
>the code it is not immediately obvious from the form of the function call that
>a variable might be changed by the function.
Like when you pass an array in C?
> With the address passed explicitly
>it is clearer that this is a VAR parameter (as we ex-Pascal types say :).
No, it isn't. A responsible C++ programmer will make intelligent use
of the "const" keyword to distinguish between read-only and "write/modify"
access, e.g.
int foo(const thing &baz) baz is read-only, passed by reference
int foo(thing &baz) baz is writable, passed by reference
A decent C programmer can do the following:
int foo(const thing *baz) baz points to a read-only segment
int foo(thing *baz) baz points to a writable segment
>Often it is clear from
>context that a variable is being changed.
If isn't clear, you are probably doing something wrong.
davisonj@ecn.purdue.edu
Author: berczuk@world.std.com (Stephen P Berczuk)
Date: 14 Apr 92 14:08:11 GMT Raw View
A couple of things to keep in mind:
1) Having a reference argument prevents you from having optional
arguments or default values for user defined classes (at least for
the moment..) for example you can have a function like:
foo(myclass* xx=NULL){ if(xx=NULL) // use default values}
but not... foo(myclass&=defaultValue);
2) In past work I have done it was generally considered good form to use
reference args only when the arg is const so that there is NO confusion
about whether the arg can be side-effected. eg, foo(const aClass& x)
not foo(aClass& x). of course this is a matter of local convention,
but is is probably safer to stick to using referneces as a means of
saving object copies (without resorting to pointers, which muddy the
syntax at times...)
I also seem to recall having conversations about virtual functions on derived
classed not working right w reference arguments, but I may be confusing this
with something else...
-steve berczuk
berczuk@world.std.com
Author: jak@cs.brown.edu (Jak Kirman)
Date: Tue, 14 Apr 1992 17:47:20 GMT Raw View
In article <BMpB9o.rp@world.std.com> berczuk@world.std.com (Stephen P Berczuk) writes:
> 1) Having a reference argument prevents you from having optional
> arguments or default values for user defined classes (at least for
> the moment..) for example you can have a function like:
> foo(myclass* xx=NULL){ if(xx=NULL) // use default values}
> but not... foo(myclass&=defaultValue);
Indeed you can:
class MyClass { };
static MyClass fooDefault;
void foo (MyClass& a = fooDefault)
{
if (&a == &fooDefault)
{
// default was used
}
// etc.
}
main ()
{
MyClass x;
foo ();
foo (x);
}
This works on AT&T 3.0.1 and Sun 2.1.
There is some name-space pollution, of course; it would be nice if the
default argument could be a static member of the function...
> 2) In past work I have done it was generally considered good form to use
> reference args only when the arg is const so that there is NO confusion
> about whether the arg can be side-effected. eg, foo(const aClass& x)
> not foo(aClass& x). of course this is a matter of local convention,
> but is is probably safer to stick to using referneces as a means of
> saving object copies (without resorting to pointers, which muddy the
> syntax at times...)
On the whole I would agree, though obviously there are cases where
pointers are not an option, such as operators. Also, there are cases
where the semantics are obvious, and pointers simply complicate things;
a trivial example of this is a swap function.
Jak Kirman jak@cs.brown.edu
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
No matter how happily a woman may be married, it always pleases her to
discover that there is a nice man who wishes that she were not.
-- H.L. Mencken
Author: rmartin@willing.Rational.COM (Bob Martin)
Date: 15 Apr 92 00:06:01 GMT Raw View
lam@saifr00.cfsat.honeywell.com (Josh Lam) writes:
>In C++, call by reference can be accomplished using pointers (like in C) or
>by reference (&). Question: What are some advantages of using references
>over pointers (or vice versa)
The form:
void f(TYPE&);
is prefered over the form:
void f(TYPE*);
There are several good reasons for this. First, from the caller's
point of view there is no difference between
void f(const TYPE&);
and
void f(const TYPE);
Thus, the designer of the function can choose whether a call-by-value
or a call-by-reference paradigm is used. Thus, if TYPE were a huge
structure, call by reference could be used to speed up the call. If
TYPE were a primitive, or very small struct, pass by value might be
more appropriate. The function designer can decide, and the client
never needs to know.
Secondly, the forms:
void f(TYPE*);
void f(TYPE&);
are not semantically equivalent. They both represent the
pass-by-value paradigm, but the pointer form allows the argument to be
zero, whereas the reference form does not. The reference form
*guarantees* that a real object is being refered to.
Both forms are useful, but should be used at the appropriate times.
When the pointer form is used, the called function should always
assume that the argument can be zero. When using the reference form,
the called function should never check for zero.
--
+---Robert C. Martin---+-RRR---CCC-M-----M-| R.C.M. Consulting |
| rmartin@rational.com |-R--R-C----M-M-M-M-| C++/C/Unix Engineering |
| (Uncle Bob.) |-RRR--C----M--M--M-| OOA/OOD/OOP Training |
+----------------------+-R--R--CCC-M-----M-| Product Design & Devel. |
Author: mac@coos.dartmouth.edu (Alex Colvin)
Date: 15 Apr 92 12:27:37 GMT Raw View
lam@saifr00.cfsat.honeywell.com (Josh Lam) writes:
>In C++, call by reference can be accomplished using pointers (like in C) or
>by reference (&). Question: What are some advantages of using references
>over pointers (or vice versa)
>Thus,
>void func1(int & i) // reference method
>is 'preferred' over
>void func2(int * i) // pointer method
One advantage of the older pointer method is that the caller makes it
explicit that the integer (*i) is subject to change.
References are handy for those cases where addresses are passed just
in order to avoid copying data
--
Alex Colvin
New England Digital
mac@cs.virginia.edu
Author: lewis@sophists.com (Lewis Pringle)
Date: Fri, 17 Apr 1992 05:30:53 GMT Raw View
In article <BMpB9o.rp@world.std.com> berczuk@world.std.com (Stephen P Berczuk) writes:
>A couple of things to keep in mind:
>1) Having a reference argument prevents you from having optional
> arguments or default values for user defined classes (at least for
> the moment..) for example you can have a function like:
> foo(myclass* xx=NULL){ if(xx=NULL) // use default values}
> but not... foo(myclass&=defaultValue);
>
What is wrong with:
void foo (myClass& arg = *0)
{
if (&arg == 0) {
// use default value
}
}
--
Reading peoples .signatures is a real waste of time.
lewis@sophists.com (Lewis G. Pringle)
Author: skochhar@cvbnet.prime.com (Sandeep Kochhar x4618 5-2)
Date: 20 Apr 92 15:57:14 GMT Raw View
In article <1992Apr17.053053.10400@sophists.com>, lewis@sophists.com (Lewis Pringle) writes:
|> What is wrong with:
|> void foo (myClass& arg = *0)
|> {
|> if (&arg == 0) {
|> // use default value
|> }
|> }
|>
The above (passing *0) as a reference argument works on my Sun C++ 2.1
compiler.
However, I have a couple of questions:
- Is the above legal according to C++ standards (ARM, ANSI, etc.) and
not just a compiler quirk?
- What does *0 conceptually mean? In my code, when an
argument is Foo&, I assume that I have an object of class Foo
being passed in and thus avoid the test
if (&arg == 0)
Doesn't passing *0 imply that a valid Foo object should exist
at address 0?
Thanks.
Author: bs@alice.att.com (Bjarne Stroustrup)
Date: 20 Apr 92 20:45:23 GMT Raw View
skochhar@cvbnet.prime.com (Sandeep Kochhar x4618 5-2 @ Computervision) writes
> In article <1992Apr17.053053.10400@sophists.com>, lewis@sophists.com (Lewis Pringle) writes:
> |> What is wrong with:
> |> void foo (myClass& arg = *0)
> |> {
> |> if (&arg == 0) {
> |> // use default value
> |> }
> |> }
> |>
>
> The above (passing *0) as a reference argument works on my Sun C++ 2.1
> compiler.
Very strange. Cfront 2.1 (on which Sun 2.1 is based) and 3.0 rejects it:
"", line 3: error: non pointer dereferenced
> However, I have a couple of questions:
> - Is the above legal according to C++ standards (ARM, ANSI, etc.) and
no.
> not just a compiler quirk?
If that.
> - What does *0 conceptually mean? In my code, when an
> argument is Foo&, I assume that I have an object of class Foo
> being passed in and thus avoid the test
> if (&arg == 0)
> Doesn't passing *0 imply that a valid Foo object should exist
> at address 0?
yes - and that wouldn't be a good idea, so it's illegal.
Author: berczuk@world.std.com (Stephen P Berczuk)
Date: Mon, 20 Apr 1992 21:51:25 GMT Raw View
-------
The above (passing *0) as a reference argument works on my Sun C++ 2.1
compiler.
However, I have a couple of questions:
- Is the above legal according to C++ standards (ARM, ANSI, etc.) and
not just a compiler quirk?
- What does *0 conceptually mean? In my code, when an
argument is Foo&, I assume that I have an object of class Foo
being passed in and thus avoid the test
if (&arg == 0)
Doesn't passing *0 imply that a valid Foo object should exist
at address 0?
----
let me clarify a point about my orignial post..
when I said that the reference form prevents passing default args I was
thinking more along the lines of temporary >>OBJECTS<<. having a null
pointer makes sense sometimes in the sense of "if we have been passed
an allocated object, use it, otherwise do a default, or allocate a new
object"
by passing default object arguments I was thinking more along the lines
of foo(int& x=23){//...}
what I have often felt a need to do was have a function declaration of the
form foo(myClass& x= myClass(//stuff). now I realise that that syntax doesn't
work even if you have non reference arguments, but since the question addresses
the difference between reference and pointer arguments I suggested that
in situations where there is some default behaviour required if an arg is not
passed that the pointer syntax is preferable..
while you can say foo(myClass& x=*NULL), I donlt think it has much meaning
and will probably cause more confusion than doing pointer dereferencing.
steve berczuk
berczuk@world.std.com
Author: jimad@microsoft.com (Jim ADCOCK)
Date: 22 Apr 92 22:22:31 GMT Raw View
In article <3067@cvbnetPrime.COM> skochhar@cvbnet.prime.com (Sandeep Kochhar x4618 5-2) writes:
|In article <1992Apr17.053053.10400@sophists.com>, lewis@sophists.com (Lewis Pringle) writes:
||> What is wrong with:
||> void foo (myClass& arg = *0)
||> {
||> if (&arg == 0) {
||> // use default value
||> }
||> }
||>
|
|The above (passing *0) as a reference argument works on my Sun C++ 2.1
|compiler.
|However, I have a couple of questions:
| - Is the above legal according to C++ standards (ARM, ANSI, etc.) and
| not just a compiler quirk?
The above is not legal according to the working position of the ANSI-C++
committee. Strict "legality" on this issue is not established until
the ANSI-C++ standard goes through final vote some indefinite time in
the future.
Also, not yet clearly established is what "constraints" C++ compilers
have when presented with one or another "illegal" construct such as the above.
One possibility is that this, that or another could be labeled "unconstrained
errors." An "unconstrained error" represents something that programmers
are not suppose to do, but which compiler are allowed to take any action
to when presented with the problem. I suspect that C++ compilers today
and in the future will take some ill-defined combination of the following
actions, depending on the exact schenerio where the null reference occurs:
* generate "correct" code and/or
* generate "incorrect" code and/or
* issue an error and/or
* issue a warning and/or
* cause a runtime trap and/or
* cause a runtime error and/or
....
| - What does *0 conceptually mean?
Conceptually it means that the programmer has made an error.
In my code, when an
| argument is Foo&, I assume that I have an object of class Foo
| being passed in and thus avoid the test
| if (&arg == 0)
I agree with your programming convention.
| Doesn't passing *0 imply that a valid Foo object should exist
| at address 0?
No, it implies the programmer has written an illegal program.