[comp.lang.c++] Naive style question

dan@kfw.COM (Dan Mick) (06/29/91)

I'm just starting with C++, and I'm pondering the issue of reference types.

For example, the oft-quoted example of 

void swap(int& i, int& j)
{
	int tmp;

	tmp = i; i = j; j = tmp;
}

Obviously, you'd use this with "swap(i,j);" as opposed to the C version with
pointers, which has to appear "swap(&i, &j);". 

My problem with this is that, as a maintenance programmer, you have to know
all about swap()s signature before you can know that swap(i,j) does or
doesn't change its parameters in the caller's scope, whereas with the
pointer version as in C, you *know* the caller's variables can't be changed
by the function unless their address is passed. 

It seems to me that the confidence inherent in pass-by-value is a big part of 
maintaining C code; in fact, it's one of the real advantages, to me, over
languages that support pass-by-reference, especially those that support pass-
by-reference with syntax *in the callee*.  

What do you all think?

Are reference types more of a hassle than they're worth?

Does this mean that it's insane to think about programming in C++ unless you've
got a *great* tags/class-browser system?

(Of course, this also opens the can of worms about overloaded functions and
operators...can you ever know what "+" means again?...but let's leave that
particular issue for another time...)

steve@taumet.com (Stephen Clamage) (06/29/91)

dan@kfw.COM (Dan Mick) writes:

>I'm just starting with C++, and I'm pondering the issue of reference types.
>void swap(int& i, int& j) ...

>My problem with this is that, as a maintenance programmer, you have to know
>all about swap()s signature before you can know that swap(i,j) does or
>doesn't change its parameters in the caller's scope, whereas with the
>pointer version as in C, you *know* the caller's variables can't be changed
>by the function unless their address is passed. 

This is true, and is a common criticism of reference parameters in C++,
and var parameters in Pascal.  But reference types are required to
implement a number of desirable features of C++.

C++ requires prototypes, so you know that a prototype for swap() is in
scope.  You look at the prototype, and if it has non-const reference
parameters, you must assume that the parameter values may be changed.
If the reference parameters are const, you may assume they are not
changed.  Example:
	foo(T1&, const T2&);
You must assume that the first parameter, of type T1, may be changed
by function foo.  If you study the function body and find that it
does not change its first parameter, that does not mean that a future
version will not change it.  But you may assume that foo does not
change its second parameter, of type T2.  Beware of programmers who
silently change the prototype of a function.

It is possible to change a const reference parameter within a function
by using a cast, but that is a dangerous programming practice.  Not only
are clients of the function entitled to assume that the parameters are
not changed, but the compiler will assume so too, and may generate code
which will fail if that assumption fails.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com