And now this pointer bullshit is confusing EVERYONE!
Brandon Allbery
allbery at ncoast.UUCP
Tue Jul 1 08:40:19 AEST 1986
Expires:
Quoted from <4609 at sun.uucp> ["Re: My pointer stuff: C caught me again (?) but it has truths in it"], by guy at 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 at 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)
More information about the Comp.lang.c
mailing list