[net.unix] C'mon, guys!

allbery@ncoast.UUCP (Brandon Allbery) (05/25/86)

Expires:

Quoted from <357@dg_rtp.UUCP> ["Re: allocating arrays"], by throopw@dg_rtp.UUCP (Wayne Throop)...
+---------------
| > david@ukma.UUCP (David Herron)
| >> throopw@dg_rtp.UUCP (Wayne Throop)
| >>> allbery@ncoast.UUCP (Brandon Allbery)
| >>> | ???
| >>> | Consider an array of 15 pointers to arrays of doubles:
| >>> |     double (*parray[15])[];
| 
| >>> double (*parray[15])[]; means:
| >>>       an indefinitely-sized array of (or a pointer to)
| >>>               an array of 15
| >>>                       (double *)
| 
| >>Wrong.  It means just what the original poster said it meant.  It is an
| >>array of 15 pointers to arrays of double.
| 
| > I respectively submit that you're full of it and that Brandon is correct.
| 
| I exasperatedly submit that I'm quite empty of it, and that Brandon is
| as wrong as wrong can be.  Also, after saying I'm wrong, your examples
| go on to support my position strongly, so you've succeeded in puzzling
| me no end, as well as prolonging this discussion beyond it's natrual
| span.
+---------------

I concede.  But it wasn't pointer-vs.-array that threw me; f[] and *f are
identical, whereas f[5] and *f are NOT and neither are f[] = {3} and *f.
What threw me was getting my insides and outsides confused.  C declarations
are giving me gray hairs!  Anyone for Modula-2?

The declaration is correct, the cast should be to (double **), and MSC is as
screwed up as everything else I've ever seen from Microsoft.  (So what's
new?)  I'm interested in knowing why your sys5 passed it without an illegal
pointer combo message, though.

--Brandon
-- 
decvax!cwruecmp!ncoast!allbery  ncoast!allbery@Case.CSNET  ncoast!tdi2!brandon
(ncoast!tdi2!root for business) 6615 Center St. #A1-105, Mentor, OH 44060-4101
Phone: +01 216 974 9210      CIS 74106,1032      MCI MAIL BALLBERY (part-time)
PC UNIX/UNIX PC - which do you like best?  See <1129@ncoast.UUCP> in net.unix.

guy@sun.UUCP (05/27/86)

> I'm interested in knowing why your sys5 passed it without an illegal
> pointer combo message, though.

I don't know what "it" refers to here, but if "it" is an assignment of a
pointer to an array of X to a pointer to a pointer to X, or something like
that, the reason why the PCC in question (and most other PCCs) passed it is
that PCC has a bug in it.  The type checking code in "chkpun" is completely
wrong.  It treats pointers and arrays as equivalent everywhere.  See
net.bugs.v7/net.bugs.2bsd/net.bugs.4bsd and net.bugs.usg for fixes.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.arpa

throopw@dg_rtp.UUCP (Wayne Throop) (05/30/86)

> allbery@ncoast.UUCP (Brandon Allbery)

> I concede.  But it wasn't pointer-vs.-array that threw me; f[] and *f are
> identical, whereas f[5] and *f are NOT and neither are f[] = {3} and *f.
> What threw me was getting my insides and outsides confused.  C declarations
> are giving me gray hairs!  Anyone for Modula-2?

I'm for Modula-2 too.  But you don't concede enough, apparently, since
you still think that f[] and *f are the same thing, which they are not,
and you go on to say:

> The declaration is correct, the cast should be to (double **), and MSC is as
> screwed up as everything else I've ever seen from Microsoft.  (So what's
> new?)  I'm interested in knowing why your sys5 passed it without an illegal
> pointer combo message, though.

Which is WRONG, WRONG, WRONG.  The cast should be (double (*)[]).  Many
folks still seem to think that declaring arrays of unknown size is the
same as declaring a pointer.  It is NOT so.  Apparently, I have not
convinced you yet.  Let's see what various tools say about this example:

    1    char *malloc();
    2    void f(){
    3        int (*a)[], (*b)[], (*c)[];
    4        a = (int **)    malloc( (unsigned)sizeof(int)*10 );
    5        b = (int (*)[]) malloc( (unsigned)sizeof(int)*10 );
    6        c = (int *)     malloc( (unsigned)sizeof(int)*10 );
    7    }

Well, what ought to happen here?  The assignment on line 5 is the only
one which has matching types, so everybody ought to complain about the
other two.

Our compiler doesn't raise a peep for any of the three, but this doesn't
surprise me. C compilers most often take a "parts is parts" attitude,
and ignore minor type issues if the intent is "clear".

Our local typechecker says (compressing some whitespace):

    4   inconsistent types discovered
            Types are:  (:POINTER_TO (:ARRAY_OF (:INT) () ()))
            and:        (:POINTER_TO (:POINTER_TO (:INT)))
    6   inconsistent types discovered
            Types are:  (:POINTER_TO (:ARRAY_OF (:INT) () ()))
            and:        (:POINTER_TO (:INT))

Lint, on the other hand, only complains about the assignment on line 6,
saying

    warning: illegal pointer combination
        (6)

So, much to my disgust, lint doesn't catch what I claim is a blatant
error.  So who're ya  gonna believe, me or a stupid program?  :-)
Let's see if we can't induce lint to see a difference between a pointer
and an array with unknown bounds.  Let's consider *this* example:

    1    #include "stdio.h"
    2    void f(){
    3        int (*a)[], **b;
    4        printf( "%d %d\n",
    5            sizeof *a,
    6            sizeof *b );
    7    }

This time, our compiler says

    Error 276 severity 3 beginning on line 5
    You cannot take the size of an array with unknown bounds.

Our local typechecker doesn't raise a peep (it doesn't attempt to
evaluate sizeofs).

And lint, glory be, says

    (5)  warning: sizeof returns value less than or equal to zero

So, lint *does* know the difference between an array of unknown bounds
and a pointer (it correctly complained about applying sizeof to the
array, and allowed the sizeof of the pointer), it just doesn't complain
if you try to assign a pointer-to-a-pointer to a pointer-to-an-array.
That is, lint has a bug, which answers the question as to why lint
doesn't call "illegal pointer combo" on line 4 of the first example.
Further supporting the contention that lint has a bug, it doesn't
complain about this example, which *everyone* should agree is incorrect:

    char *malloc();
    void f(){
        int (*a)[10];
        a = (int **) malloc( (unsigned) sizeof(int)*10 );
    }

In this case, lint apparently thinks that (int (*)[10]) is the same type
as (int **), clearly wrong.

Let's look at one more example.

    #include "stdio.h"
    void main(){
        int ia[10] = {1}, (*a)[] = (int (*)[])ia;
        int i = 2, pi = &i, **b = &pi;
        printf( "%x %x  %d      %x %x  %d\n",
                 a, *a, **a,    b, *b, **b );
    }

This program, when run, prints

    70000a18 70000a18  1      70000a14 70000a12  2

So, a shows the contents of the pointer a, *a is an array name, and
hence shows the address of the first element pointed to by a, and **a is
an integer, the first one in the array *a.  On the other hand b shows
the contents of the pointer b, *b is a pointer, and hence shows the
contents of a second pointer, and **b is an integer, the one pointed to
by *b.

This shows that (*a)[] is talking about two chunks of storage, one being
a pointer to the other, and the other being an array of integers (of
unknown size).  **b, on the other hand, is talking about *three* chunks
of storage, one being a pointer to the second, the second being a
pointer to the third, the third being an integer (or, implicitly, an
array of integers of unknown size).  Note that in both of these cases,
only the *first* of the chunks of storage being talked about is
allocated by the definition of a or b.

Now, have I convinced you all that (*)[] is not the same thing as **,
or must I get out.........  THE RACK!  HA HA HAAAAAA!!!

--
"I didn't expect the bloody Spainish Inquisition."
                                --- Monty Python
-- 
Wayne Throop      <the-known-world>!mcnc!rti-sel!dg_rtp!throopw

rde@ukc.ac.uk (R.D.Eager) (05/31/86)

This discussion should move to net.lang.
-- 
           Bob Eager

           rde@ukc.UUCP
           rde@ukc
           ...!mcvax!ukc!rde

           Phone: +44 227 66822 ext 7589

guy@sun.uucp (Guy Harris) (06/01/86)

> That is, lint has a bug...

Yup.  See a recent posting in net.bugs.<various flavors of UNIX> for a fix
(unless some of you people out there *want* PCC and "lint" to concur in your
mistaken belief that pointers and arrays are equivalent).  Also note that
this fix also permits "lint" to check that you aren't trying to convert a
pointer to an array of, say, 10 "int"s to a pointer to an array of 20
"int"s; that is as questionable as converting a pointer to an "int" as
converting a pointer to a "double".
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.arpa

root@ucsfcca.UUCP (Computer Center) (06/03/86)

> 
> (unless some of you people out there *want* PCC and "lint" to concur in your
> mistaken belief that pointers and arrays are equivalent).  Also note that

Or do we have confusion between name and object?

K&R, p. 186

      An array name is a pointer expression.

     p. 210

      Every time an identifier of array type appears in an
      expression, it is converted into a pointer to the first
      member of the array.

So an array is not a pointer but a reference to an array
in an expression is a pointer.

Thos Sumner    (...ucbvax!ucsfcgl!ucsfcca.UCSF!thos)

guy@sun.uucp (Guy Harris) (06/04/86)

> Or do we have confusion between name and object?
> ...
> So an array is not a pointer but a reference to an array
> in an expression is a pointer.

That's part of it, but I strongly suspect that people have been confused by
the fact that when you use an array name in an expression it really means a
pointer to the first member of the array; they interpret this limited
interchangability as meaning pointers and arrays are equivalent.

There's been a discussion in net.lang.c of features to be added to C;
sometimes I think pointers should be *subtracted* from C, since people seem
to get very confused about them.  There's plenty of code out there which
indicates that the author thinks that, because the second argument to "stat"
is a "struct stat *", that you *have* to pass it a variable of type "struct
stat *" as its second argument; they declare such a variable, set it to
point to a declared "struct stat", and pass the variable to "stat" instead
of just "&<the struct>".  Of course, there's always the code which doesn't
declare the "struct stat", and doesn't initialize the pointer, but just
passes a pointer which points nowhere to "stat"; this pops up every so often
on net.lang.c with the question "Why doesn't this work?" attached.

OK, maybe they're useful, and shouldn't be removed.  C classes should spend
*lots* more time on them than they are doing, though, given these problems;
better that people learn in class before they start writing code, than be
forced to ask several thousand people on USENET why their code doesn't work.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com (or guy@sun.arpa)

bzs@bu-cs.UUCP (Barry Shein) (06/18/86)

Guy Harris writes:
>...sometimes I think pointers should be *subtracted* from C, since people seem
>to get very confused about them...
>...OK, maybe they're useful, and shouldn't be removed.  C classes should spend
>*lots* more time on them than they are doing, though, given these problems;
>better that people learn in class before they start writing code

Being as I teach a couple of C courses a year here at BU I thought I
would comment on this, perhaps it would be of some use to language
designers (or make them give up entirely!)

It's not 'C', I've had the same basic problems with students when
teaching IBM assembler, PL/I and Pascal.

There seems to be some fundamental problem with distinguishing
"the thing" from "the thing contained"*. In english (and probably
most other natural languages) we interchange these notions very
loosely as in "The White House said today..." or "she packed a
great lunch" (it's a little subtle, think about it, "I called 411"
is a similar conceptual variant.)

Somewhere in that mess they have to retrain themselves to carefully
distinguish between these two notions and not confuse a 'box' with
it's 'contents', an address with a value contained therein, to remember
two things for one object.

It's similar to the exasperating problem of teaching recursion (another
concept we are taught in language is actually an *error*, "don't define
things in terms of themselves!")

That is, it's more fundamental then simple language design although
design can affect the learning process. I believe C is actually
superior to, say, Pascal in this regard as Pascal never removes the
mystery from pointers (one exercise I will give a student having
conceptual problems is to printf some pointers in a meaningful
way as the program runs, such as when stepping through an array
with a pointer, try that in Pascal, you'll probably get a compile-time
error from the write() statement.)

Practice helps *IF* they can get past the first conceptual hurdles,
many never do. But then again, those that don't aren't writing to
net.lang.c, they're all in Law School...

	-Barry Shein, Boston University

* An amusing anecdote I've heard attributed to Marvin Minsky (who knows)
involves him saying angrily "YOU'RE CONFUSING THE 'THING' WITH 'ITSELF'!".

phil@osiris.UUCP (Philip Kos) (06/19/86)

Barry Shein writes:
> Guy Harris writes:
> >...sometimes I think pointers should be *subtracted* from C, since people
> >seem to get very confused about them...
> >...OK, maybe they're useful, and shouldn't be removed.  C classes should
> >spend *lots* more time on them than they are doing, though, given these
> >problems; better that people learn in class before they start writing code
> 
> Being as I teach a couple of C courses a year here at BU I thought I
> would comment on this, perhaps it would be of some use to language
> designers (or make them give up entirely!)
> 
> It's not 'C', I've had the same basic problems with students when
> teaching IBM assembler, PL/I and Pascal.
> 
> There seems to be some fundamental problem with distinguishing
> "the thing" from "the thing contained"*.....
> 
> 	-Barry Shein, Boston University

I'm sure that this is the problem with with many programmers, but not
all.  I just ran into a situation yesterday here at the Hospital where
one of our programmers was falsely attributing a bug to the C compiler
because the following declaration caused the program to die of a
segmentation violation:

	static char **ptrarray = {
		"",
		"str1",
		"str2",
		"etc."
	};

The programmer found that the alternate declaration

	static char *ptrarray[] = {
		"",
		"etc."
	};

ran just fine.  The confusion was compounded by the fact that this
programmer was taught in a supposedly reputable C class that *the two
declarations were always identical*.  I explained the situation in
which the two are effectively identical (formal parameter to a
function, natch) and the reason why the first just wouldn't work the
way it was intended, and things are OK now, but I'd like to point out
here that it's not just student C programmers who get confused about
pointers, and much more care needs to be taken on both ends of the
learning exchange process to ensure that the concept is transferred
completely and correctly.

(Of course there really *is* a bug in the compiler, since it let the
original declaration through without even a peep; it's just not the bug
imagined by the programmer.  For everyone's info, the compiler is cc on
OSx v3.1 [Pyramid Computer Corp.] and I have suggested that the company
be notified of this bug.  In the meantime, can anyone tell me whether
this is a known pcc bug, or is it specific to Pyramid's cc?)


Phil Kos			  ...!decvax!decuac
The Johns Hopkins Hospital                         > !aplcen!osiris!phil
Baltimore, MD			...!allegra!umcp-cs

"People say I'm crazy, dreaming my life away..."  - J. Lennon

peters@cubsvax.UUCP (Peter S. Shenkin) (06/19/86)

In article <bu-cs.811> bzs@bu-cs.UUCP (Barry Shein) writes:
>
>Guy Harris writes:
>>...sometimes I think pointers should be *subtracted* from C, since people seem
>>to get very confused about them...
>>...OK, maybe they're useful, and shouldn't be removed.  C classes should spend
>>*lots* more time on them than they are doing, though, given these problems;
>>better that people learn in class before they start writing code
>
>Being as I teach a couple of C courses a year here at BU I thought I
>would comment on this, perhaps it would be of some use to language
>designers (or make them give up entirely!)
>
>It's not 'C', I've had the same basic problems with students when
>teaching IBM assembler, PL/I and Pascal.

Just a quick remark.  When I was learning C, I understood that "*pi" meant "the
contents of pi," but somehow had difficulty conceptualizing why the declaration
"int *pi;" declares pi as a pointer to an int;  that is, I knew it was a
convention I had to memorize, but it didn't seem mnemonic to me.  Then, about
a month ago, revelation!:  read this as "the contents of pi is an integer;"
which implies, "pi is that which contains (or points to)" an integer.  Somehow 
it made thinking about the declarations easier.  It's occurred to me that maybe
everyone else in the world sees this from day 1, but for us dumb folks, having
this reading pointed out would probably make the learning process easier....

Peter S. Shenkin	 Columbia Univ. Biology Dept., NY, NY  10027
{philabs,rna}!cubsvax!peters		cubsvax!peters@columbia.ARPA

phaedrus@eneevax.UUCP (Praveen Kumar) (06/20/86)

I believe that a lot of the notation in C is derived from PDP assembly
language.  I think (it has been long time since I mucked around with
PDPs) that the increment, "++", and the dereferencing, "*" operators are
straight out of PDP assembly.  That is, they work the same way in
PDP assembly. 

pk
-- 
"Everybody wants a piece of pie, today," he said.
"You gotta watch the ones who always keep their hands clean."

phaedrus@eneevax.umd.edu or {seismo,allegra}!umcp-cs!eneevax!phaedrus

chris@umcp-cs.UUCP (Chris Torek) (06/21/86)

[Warning: this is not an article about `C', but rather an article
about `about C'.  Nothing truly technical is contained herein.]

In article <748@eneevax.UUCP> phaedrus@eneevax.UUCP (Praveen Kumar) writes:
>I believe that a lot of the notation in C is derived from PDP assembly
>language.  I think (it has been long time since I mucked around with
>PDPs) that the increment, "++", and the dereferencing, "*" operators are
>straight out of PDP assembly.

This is not really for me to say, for I was not in on the creation
of the C language, yet I feel I should answer this.  (If I do a
good enough job, perhaps I can even provoke DMR into a few minor
corrections. :-) )  Was the C notation derived from PDP-11 assembly?
I think the answer here is both no and yes.  Much C notation was
certainly influenced by '11 assembly; but I think `derived' is too
strong.

DEC PDP-11 assemblers use `@', not `*', but let us assume that Ken
Thompson had been using `*' with whatever assembler he was using.
(The 4BSD Vax assembler uses `*', so it is reasonable to guess that
this was handed down from an earlier era.)  First contrast

	mov	*(r4)+,-(r5)

with

	*--p = **q++;

(if I have not botched the '11 assembly; I have never used an '11).
Close?  Well, somewhat: I can see a resemblance, at any rate.

Now step back a bit and consider the notation in and of itself.
We have here three basic operations: `--p', `q++', and `*'.  From
early mathematics notation we can take `-' as `subtract' and `+'
as `add'.  `*' is an abberation; it looks more like one of the
generic binary operation symbols used in group theory than anything
else (though this may depend on your terminal's font).  As for why
there are two each of `+' and `-', I think we can put that down to
the exigencies of parsing.  Now we have `-p' and `q+'---but what
might these mean?  Well, if `-' is subtract and `+' is add, then
we have `subtracted p' and `q added'.  There is nothing explicitly
being subtracted or added, so it is perhaps reasonable to assume
one of the classical computer science numbers, namely `zero', `one',
and `many'.  Adding and subtracting zero is useless, and adding
and subtracting many is ambiguous, so we will add and subtract one.
I think it is also a small step to say that the `-' is `before'
`p', and the `+' is `after' `q', so we should do the subtraction
`before' and the addition `after'.  Before and after what?  Here
I resort to fiat and say `before and after *, which we define to
mean indirection'.

Of course, all this does is demonstrate that the PDP-11 assembly
notation was in some respects `reasonable', and not that the notation
appears in C for that particular reason.  In order to refute the
quoted statement above, I must find `a lot of C notation' that does
not seem to be `derived from PDP assembly'.  So let us consider
some more C notation, in particular in expressions.

1.  Arithmetic.  C arithmetic seems to be quite conventional for
    post-FORTRAN languages.  `a + b * (c - d)' does not look much
    like a series of `sub', `mul', and `add' instructions to me.

2.  Structures.  Structure member access via `.' is again very
    conventional; it looks like PL/I, among others.  Pointer
    member access is a little different.  `p->member' can indeed
    be done with a single '11 instruction in many cases, yet
    the `->' notation itself does not appear in '11 assembly.

3.  Logical operations.  `&&' and `||' have no direct counterpart
    in '11 assembly, and must be implemented with rather complex
    series of tests and branches.

No doubt more examples can be found by those cleverer than I;
but I think this much is sufficient.  I think I will close by
saying that the notation used in C is simply a well-coordinated
set of notations borrowed from other places and languages,
including but not limited to PDP-11 assembly, and modified as
appropriate to obtain that coordination.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

campbell@sauron.UUCP (Mark Campbell) (06/21/86)

> Guy Harris writes:
> >...sometimes I think pointers should be *subtracted* from C, since people seem
> >to get very confused about them...
> > [...]
> [...] 
> It's not 'C', I've had the same basic problems with students when
> teaching IBM assembler, PL/I and Pascal.
> [...]
> Somewhere in that mess they have to retrain themselves to carefully
> distinguish between these two notions and not confuse a 'box' with
> it's 'contents', an address with a value contained therein, to remember
> two things for one object.
> [...] 	-Barry Shein, Boston University

Nicklaus Wirth, in "Algorithms + Data Structures = Programs", makes the observation
that the "goto" control structure and the pointer are analagous constructs.  It's
interesting reading.
-- 

Mark Campbell    Phone: (803)-791-6697     E-Mail: !ncsu!ncrcae!sauron!campbell

jso@edison.UUCP (John Owens) (06/26/86)

In article <487@cubsvax.UUCP>, peters@cubsvax.UUCP writes:
> Just a quick remark.  When I was learning C, I understood that "*pi"
> meant "the contents of pi," but somehow had difficulty conceptualizing
> why the declaration "int *pi;" declares pi as a pointer to an int;
> that is, I knew it was a convention I had to memorize, but it didn't
> seem mnemonic to me.  Then, about a month ago, revelation!: read this
> as "the contents of pi is an integer;" which implies, "pi is that
> which contains (or points to)" an integer.
> Peter S. Shenkin	 Columbia Univ. Biology Dept., NY, NY  10027

Maybe it's my machine-language heritage showing, but I've always found
it least confusing to think of "pi" as "the contents of pi" (which is
a pointer), "*pi" as "that which (the contents of) pi points to",
"int i" as declaring i to contain an int, and "int *pi" as declaring
pi to contain a pointer to an int.

The crucial difference is in the notions of "to contain" and "to be".
The trick is that "int i" does not mean that i *is* an int, but that i
*is* a variable which contains an int.  The expression "i" is, of
course, an int: the int which i contains.

As far as the syntax of the declaration goes, this has proven useful:

	int  pi;	(the expression)   pi    is an int
	int *pi;	(the expression)  *pi    is an int
	int  pi[2];	(the expression)   pi[i] is an int
	int *pi();	(the expression)  *pi()  is an int

	John Owens @ General Electric Company	(+1 804 978 5726)
	edison!jso%virginia@CSNet-Relay.ARPA		[old arpa]
	edison!jso@virginia.EDU				[w/ nameservers]
	jso@edison.UUCP					[w/ uucp domains]
	{cbosgd allegra ncsu xanth}!uvacs!edison!jso	[roll your own]

pete@valid.UUCP (Pete Zakel) (07/03/86)

> I'm sure that this is the problem with with many programmers, but not
> all.  I just ran into a situation yesterday here at the Hospital where
> one of our programmers was falsely attributing a bug to the C compiler
> because the following declaration caused the program to die of a
> segmentation violation:
> 
> 	static char **ptrarray = {
> 		"",
> 		"str1",
> 		"str2",
> 		"etc."
> 	};
> 
> The programmer found that the alternate declaration
> 
> 	static char *ptrarray[] = {
> 		"",
> 		"etc."
> 	};
> 
> ran just fine.
> 
> (Of course there really *is* a bug in the compiler, since it let the
> original declaration through without even a peep; it's just not the bug
> imagined by the programmer.  For everyone's info, the compiler is cc on
> OSx v3.1 [Pyramid Computer Corp.] and I have suggested that the company
> be notified of this bug.  In the meantime, can anyone tell me whether
> this is a known pcc bug, or is it specific to Pyramid's cc?)
> 
> Phil Kos			  ...!decvax!decuac

Our pcc based compiler said "warning: illegal pointer combination, op ="
and "compiler error: initialization alignment error" to the first
declaration.
-- 
-Pete Zakel (..!{hplabs,amd,pyramid,ihnp4}!pesnta!valid!pete)

pete@valid.UUCP (Pete Zakel) (07/03/86)

> Just a quick remark.  When I was learning C, I understood that "*pi" meant "the
> contents of pi," but somehow had difficulty conceptualizing why the declaration
> "int *pi;" declares pi as a pointer to an int;  that is, I knew it was a
> convention I had to memorize, but it didn't seem mnemonic to me.  Then, about
> a month ago, revelation!:  read this as "the contents of pi is an integer;"
> which implies, "pi is that which contains (or points to)" an integer.  Somehow 
> it made thinking about the declarations easier.  It's occurred to me that maybe
> everyone else in the world sees this from day 1, but for us dumb folks, having
> this reading pointed out would probably make the learning process easier....
> 
> Peter S. Shenkin

I find it a lot easier to think of "int i" as "i is an integer", "int *pi" as
"pi is a pointer to an integer", "pi" as "the address of an integer", and
"*pi" as "the integer that pi points to".  Of course, being an assembly
programmer at heart, I tend to understand the things in the way that they
are actually used by the machine.  If one thinks of "pi" as the name of a
box, then the contents of that box is the address of an integer, NOT the
integer itself.  I would think of "*pi" as the box that resides at the
address contained in "pi", which contains an integer.

In the wording used above, I would think using "the contents of what pi
points to" as a definition for "*pi" would be much better than what is 
stated above.
-- 
-Pete Zakel (..!{hplabs,amd,pyramid,ihnp4}!pesnta!valid!pete)

peters@cubsvax.UUCP (Peter S. Shenkin) (07/05/86)

In article <edison.811> jso@edison.UUCP (John Owens) writes:
>In article <487@cubsvax.UUCP>, peters@cubsvax.UUCP writes:
>> Just a quick remark.  When I was learning C, I understood that "*pi"
>> meant "the contents of pi," but somehow had difficulty conceptualizing
>> why the declaration "int *pi;" declares pi as a pointer to an int;
>> that is, I knew it was a convention I had to memorize, but it didn't
>> seem mnemonic to me.  Then, about a month ago, revelation!: read this
>> as "the contents of pi is an integer;" which implies, "pi is that
>> which contains (or points to)" an integer.
>> Peter S. Shenkin	 Columbia Univ. Biology Dept., NY, NY  10027

>
>Maybe it's my machine-language heritage showing, but I've always found
>it least confusing to think of "pi" as "the contents of pi" (which is
>a pointer), "*pi" as "that which (the contents of) pi points to",
>"int i" as declaring i to contain an int, and "int *pi" as declaring
>pi to contain a pointer to an int.
>

Like many revelations of mine, I just discovered that this one was right
there in K&R from the first;  "...I guess I was too young / to realize...":

p90:		int *px;
	is intended as a mnemonic;  it says that the combination *px is
	an int...

I also note with amazement that I used the word "mnemonic," which also
occurs in this K&R passage, in my original posting.  I rarely use that
word, yet I hadn't read that section of K&R for about two years (that I can
recall) and its purport evidently eluded me at the time.  People have
been accused of plagiarism for less....

Peter S. Shenkin	 Columbia Univ. Biology Dept., NY, NY  10027
{philabs,rna}!cubsvax!peters		cubsvax!peters@columbia.ARPA