[comp.lang.c] SUMMARY OF confusion with char *a and char aNUM

jjk@jupiter.astro.umd.edu (Jim Klavetter) (12/06/90)

Thanks everyone for the end of confusion.  In addition to the typos
(NUM+1 and ":"), it was made abundantly clear to me that you can't use
a "constant" as an lvalue:
	char a[NUM];
	char *b;

	/*  malloc b for NUM things  */
	a=strchr(string, ':');	/*   ERROR  */
	b=strchr(string, ':');  /*   CORRECT   */

Of course I knew that and I shouldn't have had to post to the net.
However, the following is ok in both cases (same declarations as
above):
	strcpy(string, a);
	strcpy(string, b);
Again, it was explained to me that a is "promoted" to type char*.  Or
another way it was put was the usual "equivalence" of pointers and
arrays (and this is what the faq list details).  

I guess my followup question is more theoretical in nature:  is this a
good thing?  Why shouldn't 
	 strcpy(string, a); 
also send an error message since the man page explicitely says that a
(in this case) is char*.  Conceptutually I understand that a copy (in
this case) is fundamentally different than an equivalence (as above
with strchr()), and also that a is unambiguous in this case, but as so
many are willing to point out:  pointers are not arrays!  (and vice
versa).  Thus, the man page is asking for a pointer, but I am giving
it an array, yet it works.

I hope I am making my confusion a little clearer, here.  It is not
that I don't understand the difference between pointers and arrays,
but that the language itself, IN SOME CASES, doesn't seem to think
there is any difference.

I'm certainly not a c basher, it just seems as if this is an
inconsistency.

Thanks once again for all the help, and I hope that this doesn't
produce TOO many flames.

jjk@astro.umd.edu
Jim Klavetter (accepting mail for Athabasca and Reudi)
Astronomy
UofMD
College Park, MD  20742

gwyn@smoke.brl.mil (Doug Gwyn) (12/06/90)

In article <7676@umd5.umd.edu> jjk@astro.umd.edu (Jim Klavetter) writes:
>I guess my followup question is more theoretical in nature:  is this a
>good thing?  Why shouldn't 
>	 strcpy(string, a); 
>also send an error message ...

This feature of C certainly can't be changed, as there are billions of lines
of existing source code written with the assumption that C works like that.

As to why Dennis made arrays second-class citizens (which is really at the
root of this kludgery), I don't know.  I would guess that since he didn't
plan to fully support them (as assignable, etc.) anyway, but still wanted
to allow the programmer to use arrays, he settled on the simplest method of
dealing with them, given that pointers are fundamental to the C language.

barmar@think.com (Barry Margolin) (12/06/90)

In article <7676@umd5.umd.edu> jjk@astro.umd.edu (Jim Klavetter) writes:
[Given the declaration: char a[NUM]; ]
>I guess my followup question is more theoretical in nature:  is this a
>good thing?  Why shouldn't 
>	 strcpy(string, a); 
>also send an error message since the man page explicitely says that a
>(in this case) is char*.  Conceptutually I understand that a copy (in
>this case) is fundamentally different than an equivalence (as above
>with strchr()), and also that a is unambiguous in this case, but as so
>many are willing to point out:  pointers are not arrays!  (and vice
>versa).  Thus, the man page is asking for a pointer, but I am giving
>it an array, yet it works.

I think Chris slipped the answer to this in the middle of one of his
responses, but it probably deserves repeating as an explicit answer to this
question.

In most cases, objects are passed to functions by value; that is, if an
argument expression is an lvalue, the contents of the location(s) specified
by that lvalue are copied to wherever the callee expects to find it
(usually the stack or registers).  The designers of C felt that this would
not be appropriate for arrays; they are often very large, and this copying
would be expensive.  So, they decided that arrays would be passed by
reference, rather than making the above syntax an error.  This was
implemented by specifying that when arrays are used in a value context they
are automatically treated as &array[0].

Basically, this is just a convenience for the programmer.  They could have
required an explicit cast, but since this use is so common it would be
quite a bother.  Also, to be completely type-proper, the reverse conversion
(passing a pointer to a function expecting an array) would require the cast
to include the size of the array.

>I'm certainly not a c basher, it just seems as if this is an
>inconsistency.

It's no less consistent than the fact that you don't generally have to cast
when assigning from an int to a long; the compiler automatically widens it.



--
Barry Margolin, Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar