swine@ccicpg.UUCP (Peter Swain) (02/18/89)
In article <807@atanasoff.cs.iastate.edu> hascall@atanasoff.cs.iastate.edu (John Hascall) writes: [ .. week-long discussion deleted .. ] >>double fund_consts[] = { >> 3.14159265, >> 2.7182818, >> 6.02E23, >>}; > > Of course, adding: > #define N_FCONSTS (sizeof(fund_consts)/sizeof(double)) > then you can use stuff like: > extern fund_consts[N_FCONSTS]; > elsewhere. In recent years, i've often gone in precisely the other direction. One of the hassles of large systems is the proliferation of names, all looking very much alike. You've just added another name (N_FCONSTS) for the programmer to remember. Admittedly the concept it embodied was tedious to type, but it was quite derivable! Try using #define dim(a) (sizeof(a)/sizeof(*(a))) and you can elegantly express the size of any array. it leads to such things as: for (i = 0; i < dim(fund_consts); i++) magic(i); or p = buf; .... while (p < &buf[dim(buf)]) stuff(*p++); where there is no question that the appropriate bound has been used. Don't you always leave out a few letters when thinking up a name to #define for a manifest constant? They all end up as N_THNGS & etc, and tend to converge in a large project. If the size of an array is a core concept, then it *should* have a name, but if it's just a collection of like things, I like to keep the dimension quite anonymous. This can go to extremes, and sometimes I've been known to say: int things[200]; /* big enuff */ int thungs[dim(things)+1]; /* one for each thing, plus sentinel */ all in order to avoid thinking of a new name. all we need now is a typeof(lvalue) operator to complement sizeof(), and i'd be happy! -- Peter Swain Softway Pty Ltd swine@softway.oz.au PO Box 305 uunet!ccicpg!swine Strawberry Hills, NSW Australia
tps@chem.ucsd.edu (Tom Stockfisch) (02/24/89)
In article <14647@ccicpg.UUCP> swine@ccicpg.UUCP (Peter Swain) writes: >In article <807@atanasoff.cs.iastate.edu> hascall@atanasoff.cs.iastate.edu (John Hascall) writes: > [ .. week-long discussion deleted .. ] >>>double fund_consts[] = { >>> 3.14159265, >>>}; >Try using > #define dim(a) (sizeof(a)/sizeof(*(a))) This doesn't work unless the defining declaration of a[] is in the same file. If it is in the same file, it probably should have been declared static. Usually "a" must be declared in a header file which cannot have access to the initialization. The scheme I use is /* header.h */ # define NELT 20 extern int a[NELT]; /* extern.c */ # include "header.h" int a[] = { 42, 666, ... }; /* compiler will complain if sizeof(a)/sizeof(a[0]) is not equal * to NELT, thus ensuring that extern.c and header.h are in sync */ Any file in the project can then get at the dimension of "a" by #include'ing "header.h". "extern.c" must NOT be int a[NELT] = {...}; because if you delete a member of the initialization set, NELT becomes out of sync without the compiler being able to complain. -- || Tom Stockfisch, UCSD Chemistry tps@chem.ucsd.edu
guy@auspex.UUCP (Guy Harris) (02/25/89)
> int a[] = { 42, 666, ... }; You forgot 23 :-) > /* compiler will complain if sizeof(a)/sizeof(a[0]) is not equal > * to NELT, thus ensuring that extern.c and header.h are in sync > */ No, it won't necessarily. It'll complain if the list of initializers contains *more* than NELT elements; however, if it contains *fewer* elements, it'll just silently initialize the rest to 0. If this is acceptable, fine, but if you want to make sure you initialize it with *exactly* NELT elements, you need more help than the compiler will give you....