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