[comp.lang.c] Double inderection question

pomeranz@cs.swarthmore.edu (Hal Pomeranz) (08/03/88)

Consider the following:

char array[10], **ptr;

main()
{
   ptr = &array;
   .
   .
   .
}

Now, when I try and compile this program with our C compiler (Sun OS 4.0), I
get something like 'warning: & before array or function: ignored'.  I've also
tried '&&array[0]', '&&(array[0])', '&(&array[0])', etc. and none of these
has worked.  From my limited understanding 'array' is a pointer to the first
element (i.e. a pointer to array[0]), so &array should be a pointer to the
pointer.  It is possible that I'm inferring too much from K&R, but this seems
like a reasonable extension of the rules they lay down.  So my question is:
where does the fault lie?  With my understanding?  With the C compiler?  Or
(*gasp*) with K&R for not making consistant rules?  As a side point, the 
following does work:

char array[10], **ptr, *bogus_ptr;

main()
{ 
   bogus_ptr = array;
   ptr = &bogus_ptr;
   .
   .
   .
}

It strikes me that if I can do what I want in this roundabout way, I should
also be able to do it directly.

Hal Pomeranz
-- 
______________________________________________________________________________
|UUCP: ...!rutgers!bpa!swatsun!pomeranz          | Living on a lighted stage
|CS Net: pomeranz@cs.swarthmore.edu              |    approaches the unreal...
|BitNet: vu-vlsi!swatsun!pomeranz@psuvax1.bitnet |                  -Rush

rob@kaa.eng.ohio-state.edu (Rob Carriere) (08/03/88)

In article <2001@tulum.cs.swarthmore.edu> pomeranz@cs.swarthmore.edu (Hal Pomeranz) writes:
>
>Consider the following:
>
>char array[10], **ptr;
>
> [ and now ptr cannot be assigned the value &array ]

This is as it is supposed to be.  Consider: the name of array *does*
(as you said) represent a pointer to the start of the array, but, and
this is the crucial fine print, NO STORAGE HAS BEEN ALLOCATED FOR THAT
POINTER!  It is a compiler constant.  One way to look at this is to
say that what you are doing is similar to:

int *foo = &1;

Which is also wrong (thank God!  One language called FORTRAN is quite
enough!).

Now in your second fragment, *you* create a space for this array
pointer to go, and then you *can* refer to it to your hearts content.
Carrying on my metaphor, this is similar to:

int  bar = 1;
int *foo = &bar;

Which will work too.

Summary: there was nothing *wrong* with the rules, they were just a
little ( :-) obscure.  

Rob Carriere

guy@gorodish.Sun.COM (Guy Harris) (08/03/88)

> Consider the following:
> 
> char array[10], **ptr;
> 
> main()
> {
>    ptr = &array;
>    .
>    .
>    .
> }
> 
> Now, when I try and compile this program with our C compiler (Sun OS 4.0),

Or most, if not all, other PCC-based compilers....

> I get something like 'warning: & before array or function: ignored'.  I've
> also tried '&&array[0]', '&&(array[0])', '&(&array[0])', etc. and none of
> these has worked.  From my limited understanding 'array' is a pointer to the
> first element (i.e. a pointer to array[0]), so &array should be a pointer to
> the pointer.

No.

"array" is a pointer-valued expression that points to array[0].  It is not a
pointer variable, or other pointer object, so you can't construct a pointer to
it - there wouldn't be anything for it to point to.

Consider:

	int *i;

	i = &666;

The compiler will not find that construct at all amusing, since there's no
object to which "666" refers (no, there's no guarantee that the compiler
allocates a data location to hold the 666).  "&array" is a similar case.

Now, in the language specified by recent drafts of ANSI C, "array" does not
refer to "&array[0]" in certain contexts.  One of those contexts is that of the
operand of "&"; thus, "&array", in ANSI C (a shorthand for "the language
specified by recent drafts of ANSI C"), is a pointer to the array named
"array".  In your example, "&array" would have type "pointer to array of 10
'char's".  It would, in most implementations, evaluate to a pointer with the
same bit pattern as "&array[0]".

> As a side point, the following does work:
> 
> char array[10], **ptr, *bogus_ptr;
> 
> main()
> { 
>    bogus_ptr = array;
>    ptr = &bogus_ptr;
>    .
>    .
>    .
> }
> 
> It strikes me that if I can do what I want in this roundabout way, I should
> also be able to do it directly.

Nope.  Nothing roundabout there.  Consider:

	int *i, iii;

	iii = 666;
	i = &iii;

If you want a pointer to an object that is a pointer to "array", you first have
to construct that object....

gwyn@smoke.ARPA (Doug Gwyn ) (08/03/88)

In article <2001@tulum.cs.swarthmore.edu> pomeranz@cs.swarthmore.edu (Hal Pomeranz) writes:
>char array[10], **ptr;
>   ptr = &array;
>From my limited understanding 'array' is a pointer to the first element
>(i.e. a pointer to array[0]), so &array should be a pointer to the pointer.

NO.  "array" is the name of the array.  In MOST expression contexts (but
not all) it is converted to a pointer to the first member of the array
before it is used.

"&array" should give you a pointer to the array (not to its first element),
but many older compilers treat it the same as an unadorned "array".

>char array[10], **ptr, *bogus_ptr;
>   bogus_ptr = array;
>   ptr = &bogus_ptr;

"bogus_ptr" IS a pointer to char; in the context of the first assignment,
"array" is converted to a pointer to array[0] before being copied into
"bogus_ptr".  "ptr" is a pointer to "bogus_ptr" and only has anything to
do with "array" by virtue of the fact that you made "bogus_ptr" have
something to do with "array".

ark@alice.UUCP (08/03/88)

In article <2001@tulum.cs.swarthmore.edu>, pomeranz@swatsun.UUCP writes:

> char array[10], **ptr;
 
> main()
> {
>    ptr = &array;
>    .
>    .
>    .
> }
> 
> Now, when I try and compile this program with our C compiler (Sun OS 4.0), I
> get something like 'warning: & before array or function: ignored'.

Many C compilers treat `array' as equivalent to `&array[0]'
in this context.  Strictly speaking, a compiler that does this
ought to be entitled to treat `&array' as `&(&array[0])', which
is illegal as (the inner) & does not yield an lvalue.

However, the compiler figures that when you said &array you mean
&array[0], so it quietly translates it for you.

In any event, such a compiler treats &array as a char * and not
as a char **, so the assignment should elicit an error message.

This all changes in ANSI C.  There, &array is actually a pointer
to the array!  Its type is `pointer to array of 10 characters'
and it might be used this way:

	char array[10];
	char (*p)[10];

	p = &array;

I have it on good authority that this is valid ANSI C, and indeed
other C compilers I've tried will accept all but the last line.

The real question is: what do you want?  You sound like you want
ptr to point to another pointer, which in turn points to the
initial element of the array.  If so, the only way to do it
is to declare the intermediate pointer explicitly: C is not in
the habit of manufacturing temporary lvalues.

Incidentally, my book `C Traps and Pitfalls' discusses the
relationship between arrays and pointers in some detail.

swarbric@tramp.Colorado.EDU (Frank Swarbrick) (08/05/88)

This stuff is all so confusing, but anyway...  In Turbo C it seems (or
maybe not) that the address of an array is the same as the array.  ie

&array == array

whereas that is not true for a normal pointer.  The address of a pointer
is something, and the pointer at that address points to another address.
Hmm, doesn't sound like it makes much sense, but it does to me.  Of course
you cannot tell an array to point at anywhere but itself.  Hmm, I really
wish I could be clearer about this.  I'll try to do a little more thinking
and then post something later.

Frank Swarbrick (and, yes, the net.cat)           swarbric@tramp.Colorado.EDU
...!{ncar|nbires}!boulder!tramp!swarbric
"Some people think they're gonna die some day.
 I got news, ya never got ta go."    --Ted Nugent

apm@oasis.icl.stc.co.uk (Andrew Merritt x2109) (08/08/88)

In article <8082@alice.UUCP> ark@alice.UUCP writes:
%
%Incidentally, my book `C Traps and Pitfalls' discusses the
%relationship between arrays and pointers in some detail.

Forgive my inability to recognise people from their user names, who are you?




-- 
signed:                               Andrew Merritt		(763) 2109
local:	   apm  	global:	      apm@iclbra.uucp
                                      apm@icl.stc.co.uk
MSDOS: Just say NO.        	      ...!uunet!mcvax!ukc!stc!iclbra!apm

ark@alice.UUCP (08/10/88)

In article <157@oasis.icl.stc.co.uk>, apm@iclbra.UUCP writes:
> In article <8082@alice.UUCP> ark@alice.UUCP writes:
> %
> %Incidentally, my book `C Traps and Pitfalls' discusses the
> %relationship between arrays and pointers in some detail.
> 
> Forgive my inability to recognise people from their user names, who are you?

I am Andrew Koenig at AT&T Bell Laboratories in Liberty Corner, New Jersey.

My name is in the headers of my postings when they leave alice,
but apparently it disappears somewhere in the depths of Usenet.

A few weeks ago I posted (in comp.lang.c) a few paragraphs
about the book and a table of contents.  I'll send a copy of
that information to people who send me mail requesting it.
To reach me, try ark@europa.att.com, attmail!ark, alice!ark,
or research!ark.