| The following error prone: it can be mistakenly applied to a pointer: #define LEN(NAME) (sizeof NAME / sizeof(NAME)[0]) I think gcc has a warning for this pattern now: when the size of a pointer
is divided by the size of its referent type. More importantly, it has an odd extra level of indirection. The traditional definition is: #define LEN(ARRAY) (sizeof ARRAY / sizeof (ARRAY)[0]) This means that to use LEN on an array, we have to take the address: char *array[5];
LEN(&array); // -> 5
If we use LEN(array);
which is an easy mistake, we get: sizeof *array / sizeof (*array)[0]
which is sizeof (char *) / sizeof (char)
which is sizeof (char *)
which is likely 4 or 8.I do see that LEN is supposed to be (only) used in conjunction with ARR: #define ARR(TYPE, NAME, COUNT) TYPE(*NAME)[COUNT]
but that isn't enforced. An idea would be to add some "secret" prefix or suffix to NAME like blah_ ## NAME, so that name cannot be referenced without going through the macros; i.e. if we define ARR(int, foo, 42) then there is no declared identifier foo; it actually declares blah_foo, and LEN(foo) knows about that, also adding the prefix. Thus mistakenly using LEN(foo) on something not declared with ARR will likely be a reference to an undeclared identifier. |