allbery@ncoast.UUCP (Brandon Allbery) (07/01/86)
Expires: Quoted from <4609@sun.uucp> ["Re: My pointer stuff: C caught me again (?) but it has truths in it"], by guy@sun.UUCP... +--------------- | > The code in question is two analogous sections: | > | > -------- section 1 --------- | > | > struct sfld (*__cursf)[] = (struct sfld (*)[]) 0; | > | > if ((__cursf = (struct sfld (*)[]) calloc(n, sizeof (struct sfld))) | > == (struct sfld (*)[]) 0) ... | > | > ---------------------------- | > | > This was intended to allocate an array and assign it to a variable of type | > ``pointer to array of (struct sfld). I suspect the type is wrong but I'm | > not sure how to decalre such a beastie; I suspect that it *does* *not* | > *exist* *at* *all* in C, now that I've played with it. | | Wrongo. "struct sfld (*cursf)[]" *is* a declaration of a pointer to an | array of "struct sfld". However, it is not possible to generate a value | with that type by taking the address of an object which is an array of | "struct sfld". You *can* generate a value of that type by using the name of | an array of arrays of "struct sfld"; such a name has the type of a pointer | to an element of that array, and hence the type "pointer to array of 'struct | sfld'". +--------------- Which was my point... +--------------- | (By the way, the casts of "0" are not necessary; the compiler knows that the | LHS of the "=" operator in the declaration, and the "==" operator in the | "if", is a pointer, and thus knows that it must coerce the "0" into a null | pointer of the appropriate type.) +--------------- I'm aware of it. I simply dislike sloppy coding practices like int (*foo)(); if ((foo = signal(SIGINT, blurfl)) == 0) ... and x = 3, y = -2; if (!x && !y) ... even though C sanctifies both. It just plain don't look clean. +--------------- | > This could easily have been done correctly: | > | > int array[3]; -- should declare a pointer followed by 3 integers, with the | > pointer initialized to the 3 integers | > int array[]; -- should decalre a pointer. | | No, NO, *NO*, ***N*O****, | | | N N OOOOO ! | NN N O O ! | N N N O O ! | N N N O O ! | N N N O O ! | N NN O O | N N OOOOO ! +--------------- If you had read more carefully and applied what you know of C, it would have been YES!!! Think about it for awhile. I was trying to make a language which is C-compatible but handles arrays correctly. Don't like it? Then why in the name of the Witness are you bitching about pointers-vs.-arrays??? +--------------- | > C should treat ``int array[]'' as a different type from ``int *ptr'', | | It does. That's what people have been trying to tell you! +--------------- Modulo some other type not being assignable (if it's initialized or given as array[n], it's a constant value), I am again correct. Only if it can't be made a compile-time constant is it a pointer. Clear? +--------------- | > and while ``int array[3]'' and ``int array[]'' are the same type, the sized | > array's pointer should be treated as a constant. (This may be arguable.) | | Damn straight it's arguable. NEITHER array has a "pointer" in the sense of | a location of memory which holds a pointer to that array. The name "array" | is, when used in an expression, a *constant* pointer to the first member of | that array - in *both* cases. +--------------- In terms of my proposed MOD to C, not of C itself. Read before flaming. AAUGH!!!! +--------------- | > the malloc()'ed one is type (int *), to the C compiler (to me, int []) | > the declared one is type (int []), to the C compiler | > (which defines (int []) as (int *)) +--------------- For the purposes of the compiler, the array is a constant of type (int *). Else the pointer/array problem damned well wouldn't exist. +--------------- | No, it doesn't. You haven't been listening. *Start* listening. To the C | compiler, "int []" declares an array of "int"s, which is normally | implemented as a consecutive block of locations holding "int"s. However, an | array can *not* be used as an object in an expression. You can't do array | assignment, you can't add two arrays, you can't pass arrays to functions as | arguments, and you can't have a function which returns an array. When the | name of an array is used in an expression, it is *reinterpreted* as a | *constant* pointer to the first element of that array. +--------------- C doesn't *have* arrays. ``int a[3]'' decalres three ints and a constant pointer to the first. If it declared it as an ARRAY none of this would be a problem. +--------------- | The "malloc()'ed one" is type "int []"; however, "malloc" returns a pointer | to the first element of that array. This is not much stranger than | | int *x; | x = (int *) malloc(sizeof int); | | "malloc" can't very well return an "int" here, it can *only* return a | *pointer* to what it has allocated. You *have* to declare a "pointer to | 'int'" here, even though the object which "malloc" has allocated is an | "int", not a "pointer to 'int'". The same is almost true of arrays, except | that you declare a pointer to an object of type <whatever>, rather than of | type "array of <whatever>", when "malloc"ing an array. +--------------- Reread this thing if you don't understand yet. Pay special attention to the union of this last paragraph of yours and the last one of mine. Then tell me about arrays in C. I maintain that C doesn't support arrays, it merely fakes something with semantics similar in SOME contexts. +--------------- | > and they are in fact identical in memory, so the C compiler treats them as | > identical period. | | Bullshit. A pointer to "int" and an array of "int" are in NO WAY identical | in memory. int a[3]; --> (a[0])(a[1])(a[2]) int *b = malloc(3*sizeof (int)) --> (b[0])(b[1])(b[2]) THESE are different??? -----------^^^^^^^^^^^^^^ +--------------- | > Come to think of it -- can malloc() or similar be typed right anyway? I | > suspect this is why Pascal uses the ``new(pointer)'' construct, known to the | > compiler; it's type-able at compile time. But catching the allocation of an | > (int []) (vs. an (int)) from malloc() and forcing the former to be assigned | > to a variable of type (int []) and the latter to an (int *) is nearly | > impossible even when the language considers (int []) and (int *) to be | > different. | | No, no, no! If you "malloc" an array, you don't assign the result of | "malloc" to a variable of type "int []". What you want is to be able to | assign it to a variable of type "pointer to array of 'int'" and use that | pointer to refer to that array. If you "malloc" an "int", you don't assign | the result to a variable of type "int", do you? +--------------- Conceded. So we're back to my original that was so offensive. Sigh. +--------------- | The problem here is that you don't deal with pointers to arrays in the | following fashion: | | int (*pointer_to_array)[]; | | pointer_to_array = | (int (*)[]) malloc(number_of_array_elements * sizeof int); | third_element_of_malloced_array = (*pointer_to_array)[2]; | | If arrays had been first-class types in C, this would have been how you +--------------------^^^^^^^^^^^ Golly gee, you might even understand! | would have done it. Instead, you have to do: | | int *pointer_to_first_element_of_array; | | pointer_to_first_element_of_array = | (int *)malloc(number_of_array_elements * sizeof int); | third_element_of_malloced_array = | pointer_to_first_element_of_array[2]; | /* or *(pointer_to_first_element_of_array + 2) */ +--------------- Which is what I am saying is a mistake. Glad you finally noticed. Further flames to /dev/null. C is just plain a botch. --Brandon -- ihnp4!sun!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)
guy@sun.uucp (Guy Harris) (07/02/86)
> > This was intended to allocate an array and assign it to a variable of type > > ``pointer to array of (struct sfld). I suspect the type is wrong but I'm > > not sure how to decalre such a beastie; I suspect that it *does* *not* > > *exist* *at* *all* in C, now that I've played with it. > Wrongo. "struct sfld (*cursf)[]" *is* a declaration of a pointer to an > array of "struct sfld". > Which was my point... Your point, as stated in the portion of your article that I quote, is that you suspected that there is no type "pointer to array". There is such a type. > > This could easily have been done correctly: > > > > int array[3]; -- should declare a pointer followed by 3 integers, > > with the pointer initialized to the 3 integers > > int array[]; -- should decalre a pointer. > > No, NO, *NO*, ***N*O****, ... > If you had read more carefully and applied what you know of C, it would have > been YES!!! Think about it for awhile. I was trying to make a language > which is C-compatible but handles arrays correctly. Don't like it? Then > why in the name of the Witness are you bitching about pointers-vs.-arrays??? Why in the name of "the Witness" (whatever *that* is) does providing these useless pointers make your proposed language handle array "correctly"? C handles arrays well enough for me - an array is an array, and there is no pointer involved. What languages other than BCPL and maybe B declare a pointer cell like this? PASCAL doesn't, Modula-2 doesn't, FORTRAN doesn't, etc., etc.. Do they handle arrays incorrectly? No, I *don't* like it. Those pointers are useless, and certainly don't make handing of arrays "correct". > > > C should treat ``int array[]'' as a different type from ``int *ptr'', > > It does. That's what people have been trying to tell you! > > Modulo some other type not being assignable (if it's initialized or given as > array[n], it's a constant value), I am again correct. Only if it can't be > made a compile-time constant is it a pointer. Clear? No, it is not clear, because you are NOT correct, despite any feelings you have to the contrary. The *O*N*L*Y* place where declarations of int array[]; and int *ptr; declare objects of the same type is if the "int array[]" is declaring a formal parameter. The only other place where "int array[]" can be used is as an external declaration, in which case it declares an *array* (NOT a pointer) of unspecified size; the size is set by the external DEFINITION of "array", in this or some other module. > C doesn't *have* arrays. ``int a[3]'' decalres three ints and a constant > pointer to the first. If it declared it as an ARRAY none of this would be a > problem. The above statement is completely false, unless you have a VERY strange defnition of an array. What is an array "int a[3]" other than three ints? In YOUR proposed language, "int a[3]" may declare a pointer. In C, there is no pointer declared. The expression "a" is an ARRAY-valued expression (if you don't believe me, try reading the ANSI C draft), which is coerced in MOST circumstances (NOT all - in the expression "sizeof a", it is not so coerced, and "sizeof a" has the value 3*sizeof(int)). > I maintain that C doesn't support arrays, it merely fakes something with > semantics similar in SOME contexts. The only difference between C arrays and arrays in some other languages is that array-valued expressions are coerced, in most cases, to a pointer-valued expression. That seems to cause some people problems. Other people have no problem with it at all. > int a[3]; --> (a[0])(a[1])(a[2]) > int *b = malloc(3*sizeof (int)) --> (b[0])(b[1])(b[2]) > THESE are different??? -----------^^^^^^^^^^^^^^ No, they're not different - BUT the latter is not the layout of "b", but what "b" *points to*. "a" is an array-valued expression, which is is in most circumstances coerced to a pointer-valued *expression* - said expression does not *have* a storage location. "b" is a pointer-valued expression which *does* have a storage location. "a", in those circumstances when it is NOT coerced to a pointer-valued expression, has a storage layout which is NOT the same as the storage layout of "b". End of discussion. > +--------------------^^^^^^^^^^^ Golly gee, you might even understand! I've understood C arrays and pointers from the beginning. Your condescending tone is offensive and inappropriate, since you don't seem to understand them. > Which is what I am saying is a mistake. Glad you finally noticed. > Further flames to /dev/null. C is just plain a botch. I've considered C arrays to have a problem for a while, because some people have trouble understanding them. If you want to consider C to be "just plain a botch" because of this, fine. -- Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.com (or guy@sun.arpa)