Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cornell!uw-beaver!mit-eddie!mit-amt!mit-caf!vlcek From: vlcek@mit-caf.MIT.EDU (Jim Vlcek) Newsgroups: comp.lang.c Subject: Point me in the right direction Message-ID: <1841@mit-caf.MIT.EDU> Date: 17 Feb 89 01:31:42 GMT References: <23631@watmath.waterloo.edu> Reply-To: vlcek@mit-caf.UUCP (Jim Vlcek) Organization: Microsystems Technology Laboratories, MIT Lines: 67 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, }; Should I want to add Euler's constant later, I merely splice it in at the end -- I don't have to change the dimension parameter. More important, there's no danger of forgetting to change that parameter. Also, I frequently work with static structures which are initialized at compile time, and which I pass around via pointers. Since struct foo *bar = { /* Some aggregate initialization */ }; is illegal, I use struct foo bar[] = { { /* Some aggregate initialization */ } }; which is legal and works so long as all of the elements of the struct can be initialized (unfortunately, unions cannot). This construct achieves in one declaration what I need, although it does somewhat abuse the concept of an array. I'd be interested in hearing comments on this technique. >In particular never declare a function parameter as an array. >e.g. use "char **argv;", not "char *argv[];". Since the compiler >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. Typically, however, I would use the first form for the actual pointer used for the traversal: some_fun(arglp) char *arglp[]; { char **next_arg = arglp; while (*next_arg++) { /* Party 'til you drop */ } } Presuming, of course, that you want to preserve the head of the list arglp, otherwise you could increment it directly. Conceptually, the above method is more clear in that next_arg is intended to refer to a pointer to a single item, hence the use of char **. -- Jim Vlcek vlcek@caf.mit.edu !{harvard,rutgers}!mit-eddie!mit-caf!vlcek