From: scs@adam.mit.edu (Steve Summit)
Newsgroups: comp.lang.c
Subject: Re: Pointer/address reluctance
Date: 16 Aug 92 18:05:47 GMT
Organization: none, at the moment

In article <l8kteaINNp2c@exodus.Eng.Sun.COM>, Peter van der
Linden (linden@positive.Eng.Sun.COM) writes:
> Can anyone explain the reluctance that some of the experts here
> have in equating "pointer" with "address"?

It was interesting to see this question presented this way;
I hadn't been aware of any widespread conspiracy to deprecate the
term "address."  I must hasten to admit that I personally do have
such an agenda, but it's a private thing, which I usually don't
make a big deal out of.  Apparently I did so at least once,
though, because I learn through private mail from Peter that it
was an explicit mention, in an article of mine, of my own
reluctance which prompted his query.

Several other netters have answered the question well; I found
particular resonance with the thoughts expressed by Gary Merrill
(in <Bsxn7A.H7v@unx.sas.com>) and John F. Woods (in <14807@ksr.com>).

For me, the answer has more to do with teaching and learning than
with C.  Learning is of course an involved process; it is not
quite so simple as obtaining some piece of knowledge from a book
or lecturer and having it mesh instantly.  Anything that we know
and understand well is embodied in our minds in complex structures
and associations ("models," if you will, but that's a bit of an
oversimplification) which mere words and pictures (by which we
learned them, or with which we try to explain them) can only
approximate.  Furthermore, as in the real world, there are
multiple possible mental models to describe a given concept or
system, some manifestly poorer than others.  So the process of
teaching (or, conversely, actively learning) consists in large
part of choosing words or other descriptions which have some hope
of imparting to the student a semblance of the desired mental
model, while simultaneously attempting to limit the possibility
that an undesired model will be inadvertently adopted.

This concern for inadvertent, undesired learning is inversely
proportional to the interactivity of the learning situation.
(That's why I used the word "lecturer" rather than "teacher" at
the beginning of the third paragraph.)  In a one-on-one tutorial
situation, initial forays down blind alleys and tortuous paths
can be quickly recognized and corrected.  But in a lecture,
book, or article, or any forum where dialogue is restricted (and,
interactive and quasi-real-time as it is, Usenet still qualifies),
using the wrong words to describe something can lead to a lot of
unnecessary frustration for the learner.

Returning to C, let us consider pointers.  There are two widely-
accepted, internally consistent models for pointers:

     1.	A pointer is the machine address of an object; it behaves
	in many respects as an unsigned integer of some size.
	Pointer arithmetic involves multiplication by the size of
	the object pointed to; this multiplication is performed
	implicitly and automatically by the compiler.

     2.	A pointer is an abstract entity which can point to other
	things.  It is somewhat easier to describe graphically
	than verbally: it can be drawn as a little box which
	either contains the notation 0/nil/NULL, or contains one
	end of an arrow which points at some other box, or
	occasionally contains garbage which we'd better not
	inquire too closely about.  When the pointer points at
	a box which is part of an "array" of contiguous boxes,
	pointer arithmetic is equivalent to moving the arrow
	forwards or backwards in the array.

Now, before I start talking about which of these models might
be "better," let me admit that for many years my own model was
essentially number 1.  For the first one or two of those many
years, though, I had quite a few problems with pointers (as does,
of course, almost everyone who learns C), so it is not a perfect
learning tool, even aside from its accuracy as a model.

One of the problems with model 1 is explicit in its last sentence
as I have worded it.  It can be difficult to remember that the
multiplication by the size of the object pointed to is performed
implicitly.  I pay particular attention to the frequency with
which questions and problems occur on comp.lang.c, but I think
many of you will agree that it is not at all uncommon for people
to write things like

	int *ip;
	...
	ip += sizeof(int);

when they really mean

	ip++;

Aside from this particular potential mistake, model 1 is (in my
opinion) unnecessarily concrete.  It encourages (nay, requires)
thinking about machine-level details, when one of the whole
points of using a higher-level-language is supposed to be to
avoid thinking about those details.

It should come as no real surprise (although some of you are
probably already groaning and/or protesting for various reasons)
that I am going to tout model 2 as both more accurate and a
better learning tool.  It is, of course, essentially the model
described in the ANSI C Standard (see particularly the
description of pointer arithmetic in section 3.3.6).  It is also
closer to the model likely to be used by certain nontraditional
machine architectures without "flat" address spaces (e.g. LISP
machines and tagged architectures).  Finally, model 2 is (I
think; one of the problems with teaching and learning and in fact
with almost every human endeavor is that self-analysis is hard)
the model that I now use myself when thinking about pointers in
C, and I find it very quick, easy, natural, and accurate to use.

It is an unproved hypothesis of mine that careless use of the
word "address" promotes adoption of model 1.  Of course I'm not
claiming that mere mention of the word instantly instills a
fully-formed, irrevocable, wrong model in the mind of the
unprepared and uninitiated listener.  But I do believe that if
you're using the word "address," you're probably tending to
describe model 1.  You're probably saying things like "Well, for
example, on the VAX, ints are four bytes, so adding 1 to an int
pointer really adds 4."  And (to continue the unproved hypothesis)
I think these descriptions and concrete examples are at least as
likely to impart a degree of confusion, or lead to future
mistaken assumptions, as they are to lead to True Enlightenment.

A couple of years ago, when we were having a similar discussion
here, someone (it may have been Stan Brown) pointed out that
there are at least two kinds of learners: those who eagerly
accept and appreciate abstract concepts, and those who insist
upon concrete examples.  There is no question but that model 1
is more concrete, and model 2 is more abstract.  It may well be
that, even if you agree that model 2 is "better," it can be
important to use model 1 as a learning tool; that is, that people
who require concrete examples cannot learn model 2 immediately,
but rather must first learn, and then un-learn, model 1.
(There's nothing wrong with this; learning curves cannot always
be monotonic.)  It is because of this possibility that I label my
hypothesis (that it's undesirable to talk about addresses when
teaching pointers) as unproven, and I don't (I hope!) go around
crusading against the word "address."  (It is certainly the case
that, as high-level-languages go, C is relatively low level, and
that good understanding of, and successful programming in, C
tends to require some thinking about machine-level details.)

The situation is a little bit like gotos.  We shouldn't try to
ban gotos (though of course many people do try); the (inverse)
correlation between goto incidence and program goodness is not
absolute.  But if you try to avoid gotos, your programs will tend
to be better.  I think (remember, this is still unproved) that if
you try to avoid talking about machine addresses, your explanations
of pointers will tend to be more successful, in that your
audience will gain a better understanding and make fewer mistakes.

It is difficult to talk about any of this without sounding
offensively superior; I could easily be criticized for being
elitist: "That snotty scs thinks we're too stupid to hear about
machine addresses without getting confused, even though that's
how he learned pointers."  I hope no one's getting that
impression (although by the time I admit the possibility, I'm
already at risk).  Pointers are traditionally a notoriously
confusing (probably the most notoriously confusing) aspect of C,
and I'm interested in figuring out how to reduce that confusion.

Actually, it's another unproved hypothesis of mine that pointers
are actually pretty easy to understand well, and that many of the
problems people are having when they think they're having pointer
problems are really memory allocation problems.  But this article
is long enough; memory allocation is a topic for another article,
or another day.

					Steve Summit
					scs@adam.mit.edu
Newsgroups: comp.lang.c