rbutterworth@watmath.waterloo.edu (Ray Butterworth) (12/15/87)
Isn't it amazing how many people are confused by such a simple concept as the address of an array? If only K&R hadn't tried to "optimize" out this idea, I don't think there would be any of this confusion (at least no more than there is for the concept of the address of a structure). Anyway, one thing I like about this ability in modern versions of C is for passing arguments to a function. Often one passes in a pointer to an array of some fixed size and it is nice to be able to declare it this way and have lint check that it is correct in the function. e.g. func(buf, junk, stuff) int (*buf)[BUFDIM]; /* pointer to an array of 10 ints */ int (*arr)[]; /* pointer to an array of ints */ int *stuff; /* pointer to an int */ int no_work[4]; /* array of 4 ints (not true) */ { *stuff = no_work[0] + (*arr)[0] + (*buf)[0]; } main() { extern int buffer[BUFDIM]; extern int array[27]; extern int would_be_nice[4]; auto int result; func(&buffer, &array, &result, would_be_nice); return result; } Under K&R C, all four parameters would be declared as "int *param;". But with &array in the language, lint can check that the first parameter was actually a pointer to an array of the appropriate size and that the second was a pointer to an array and not simply a pointer to a single int. It also makes it more obvious to the programmer that for "int *stuff;", stuff is a pointer to a single integer, while "int (*arr)[];", arr is a pointer to an array of integers. It is unfortunate that parameter "int no_work[4]" must be silently turned into "int *no_work;", and the argument "would_be_nice" must be silently turned into "&would_be_nice[0]" by the compiler. That's one big step that I wish the ANSI people had taken. Obviously there were too many objections on the ground that it would break existing code in which parameter declarations are made using array notation. But since prototypes are new and so don't affect existing code, they should at least have either 1) allowed prototypes of the form x[n] to be actual arrays 2) disallowed prototypes of the form x[] or x[n], so that future versions of the language could allow (1) without breaking anything. (And if the "*" indirection operator could be used on the right instead of the left (as any sensible language would have it), we wouldn't need all those silly parentheses. e.g. "int x*[]" pointer to an array of ints, y = x*[2]; e.g. "int x[]*" array of pointers to ints, y = x[2]*; would be so much simpler. :-)
karl@haddock.ISC.COM (Karl Heuer) (12/17/87)
In article <15869@watmath.waterloo.edu> rbutterworth@watmath.waterloo.edu (Ray Butterworth) writes: >Anyway, one thing I like about this ability in modern versions of C >is for passing arguments to a function [which can then be typechecked]. I'm glad someone mentioned this. One good example is setjmp(), which really ought to take the address of a jmp_buf (rather than the value) as argument. >But since prototypes are new and so don't affect existing code, they should >at least have either >1) allowed prototypes of the form x[n] to be actual arrays >2) disallowed prototypes of the form x[] or x[n], so that future > versions of the language could allow (1) without breaking anything. Exactly what Mark Brader and I have been saying. Unfortunately, I think the good people at X3J11 have determined (probably correctly) that (1) is too much work at this point, and have overlooked the benefits of (2). (Or, more precisely, overlooked the costs of not doing (2).) Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint