
Thomas Davie wrote:
I'm not familiar with your C++ example (not being familiar with C++), but I think that it's a bit of a stretch of the imagination to say that C "introduces a variable of type "array of 50 ints"", the fact that this is now an array of 50 integers is never checked at any point in the compilation or run, and I'm not sure it can be even if K&R had wanted to.
The size is taken into account when such array type is an element of another array, and by sizeof.
int (*p)[50]; /* p may legally point only to arrays of 50 ints each */ ++p; /* p is assumed to point into an array, and is moved by one element, i.e. by 50 ints */ I'm not sure what you're trying to prove by saying that... There is still no type information that says that the contents of p are an array of 50 elements...
Put it this way, then: 1 void foo(void) 2 { 3 int a[2][50]; 4 int b[2][60]; 5 int (*p)[50]; 6 7 p = a; 8 p = b; } $ gcc -c -Wall foo.c foo.c: In function `foo': foo.c:8: warning: assignment from incompatible pointer type In line 7, an expression of type "int (*)[50]" is assigned to a variable of type "int (*)[50]", which is OK. In line 8, an expression of type "int (*)[60]" is assigned to a variable of type "int (*)[50]", and the compiler complains.
I can still attempt to access element 51 and get a runtime memory error.
That's because C doesn't do bounds checking on array accesses. It has nothing to do with types.
The type of p is still int**,
No it isn't. "int**" and "int (*)[50]" are different types and have different run-time behaviour.
not "pointer to array of 50 ints"
Yes it is. The semantics of C pointer arithmetic mean that the size of
the target is an essential part of the pointer type.
In C, arrays and pointers are *not* the same thing. They are often
confused because C does several automatic conversions:
1. When used as an expression (rather than an lvalue), arrays are
automatically converted to pointers. Arrays only ever occur as
lvalues, never as expressions.
2. In a declaration, the x[...] syntax indicates that x is an array,
but in an expression, x must be a pointer (which includes an array
which has been converted to a pointer due to rule 1 above).
3. When declaring function arguments, you can use "T x[]" or "T x[N]"
as an alternative syntax for "T *x"; x is still a pointer, regardless
of the syntax used.
--
Glynn Clements