We all know the classic version of counting the number of elements in a C array: sizeof(a)/sizeof(*a)
But this is dangerous, because if used on a pointer it will return garbage values.
So I made this macro, utilizing gcc extensions. As far as I can tell, it works the way it is supposed to, which is causing compiler error when used on a pointer instead of array.
#define COUNT(a) (__builtin_choose_expr( \
__builtin_types_compatible_p(typeof(a), typeof(&a[0])), \
(void)0, \
(sizeof(a)/sizeof(a[0]))))
/* Only to demonstrate how to use the macro. It's not part of the code
I want reviewed. */
int main(void)
{
int arr[5];
int *p;
int x = COUNT(arr);
// This line will yield the compiler error:
// error: void value not ignored as it ought to be
int y = COUNT(p);
}
Any suggestions? Have I missed anything crucial?
1 Answer 1
We need to protect a
when it's an expression - we've put parens around a[0]
where we should have put them around a
:
(sizeof(a)/sizeof(a)[0])
For the same reason, I think that the second typeof
should be
typeof(&(a)[0])
I have to admit that I can't easily contrive an expression of array type where the parens make a difference, but better safe than sorry...
int x
and notsize_t x
, the type returned by the division? \$\endgroup\$void
on the last line of yourmain
? What are you trying to illustrate here? \$\endgroup\$