Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!iuvax!watmath!rbutterworth From: rbutterworth@watmath.waterloo.edu (Ray Butterworth) Newsgroups: comp.lang.c Subject: Re: Point me in the right direction Message-ID: <23718@watmath.waterloo.edu> Date: 17 Feb 89 15:47:09 GMT References: <23631@watmath.waterloo.edu> <1841@mit-caf.MIT.EDU> Organization: U of Waterloo, Ontario Lines: 136 In article <1841@mit-caf.MIT.EDU>, vlcek@mit-caf.MIT.EDU (Jim Vlcek) writes: > rbutterworth@watmath.waterloo.edu (Ray Butterworth) writes: > >Another handy style guideline to follow is trying to avoid writing > >empty [] declarations. If the [] is empty, then you are talking > >about an array of unknown size and in the event that you really do > >want the array there is no way that the compiler will know how big > >it is. If you don't know how big an array is, then perhaps you > >shouldn't be talking about arrays but about pointers. > > No one caught this? A compiler must be able to determine for itself > the size of one of the dimensions of an array (I believe the last > dimension in the case of a superlinear array, no?), if that array is > to be initialized at compile time, provided that unambiguous > initializers are provided. In fact, for an array which is fully > initialized at compile time, an empty [] declaration is preferable: > double fund_consts[] = { > 3.14159265, > 2.7182818, > 6.02E23, > }; I guess I didn't make my context clear. I didn't mean in cases where the array is actually being defined. Your examples are perfectly legitimate, and unless one really wants to explicitly indicate how many elements there should be, it probably is best to use the empty brackets. What I was talking about was mostly intended to refer to parameter declarations. e.g. void func(list) int list[]; { list[0] = 42; } In this case the compiler does not need to know the dimension of the list. On the other hand, I'd be concerned about how an external array is used. e.g. extern int vec[]; for (i=0; vec[i] != END_LIST; ++i) ... In this case, the list has a special value flagging its end, so this use is probably ok. extern int list[]; for (i=0; i >will silently convert the second parameter declaration into the > >first for you, you might as well declare it that way in the first > >place and avoid confusing yourself and others. > > I wouldn't say this. I like the use of ``foo *bar[]'' to make it > clear that ``bar'' does indeed represent an array of pointers, through > which one might traverse. So long as you realize that in void func(list) int list[]; {extern int vec[]; ...} the identifiers list and vec have very different types. vec is an array and list is a pointer. Many people find this feature to be a cause for confusion. Here's an example I used a while back to help a local user that couldn't understand why things were behaving the way they were: %cat sizeof.c #include test(f, d, s, c, a) float f; double d; short s; char c; int a[10]; { auto float af; auto double ad; auto short as; auto char ac; auto int aa[10]; fprintf(stdout, "sizeof autos: float=%d double=%d short=%d char=%d int[10]=%d\n", (int)sizeof(af), (int)sizeof(ad), (int)sizeof(as), (int)sizeof(ac), (int)sizeof(aa)); fprintf(stdout, "sizeof args: float=%d double=%d short=%d char=%d int[10]=%d\n", (int)sizeof(f), (int)sizeof(d), (int)sizeof(s), (int)sizeof(c), (int)sizeof(a)); } int array[10]; main() { test(0., 0., 0, 0, array); return 0; } % lint sizeof.c sizeof.c: sizeof.c(4): warning: float type changed to double sizeof.c(8): warning: array[10] type changed to pointer "fprintf" result is always ignored. % cc sizeof.c % ./a.out sizeof autos: float=4 double=8 short=2 char=1 int[10]=40 sizeof args: float=8 double=8 short=2 char=1 int[10]=4 ^ ^ * * Note that (just as lint said it would be), the parameter declarations float f; int a[10]; were silently converted by the all too helpful compiler into double f; int *a; since the first declarations were types that are not legal as function arguments. Since they are impossible as they stand, the compiler tries to help you by changing them to what you obviously meant. If you find that confuses you more than it helps you, you are not alone. But for good or bad, this is the way the C language is defined to work. On the other hand, the BSD compiler did not promote the types of the short and char parameters. That is probably a bug.