It is extremely efficient because it is a construct resulting in a compile-time constant (except for C99 VLAs, see below). You might want to use:
sizeof(array)/sizeof(array[0])
instead, so you can use it with other-than-int types. Maybe wrap it in a macro (of course, all the usual caveats about caution when using macros would apply).
On update: for my original answer above, I wasn't thinking about VLAs in C99, where:
If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant. (6.5.3.4/2)
The count of VLA array elements may only be determinable at run-time (and evaluation can itself have side-effects), so for a VLA it is not a purely compile-time construct. In most well-formed cases, the code-level behavior for a VLA will be effectively the same. For example:
#include <stdio.h>
#define countof_array(arr) (sizeof(arr)/sizeof(arr[0]))
int vlaSize(void)
{
return 8;
}
int main(void)
{
int fixed_array[9] = { 1,2,3,4,5,6,7,8,9 };
int vla_array[vlaSize()];
printf("Fixed array: size = %zu bytes, count = %zu elements\n",
sizeof(fixed_array), countof_array(fixed_array));
printf("VLA array: size = %zu bytes, count = %zu elements\n",
sizeof(vla_array), countof_array(vla_array));
return 0;
}
Result:
$ gcc -Wall -std=c99 so-misc.c
$ ./a.out
Fixed array: size = 36 bytes, count = 9 elements
VLA array: size = 32 bytes, count = 8 elements
On further edit, striking this part:
Caveat: It would not be difficult to intentionally create a case where the semantics of countof_array
would effectively differ for a VLA [...]
because after thinking about it more, I'm not sure if this is true. Asking about this in a separate question.
In any case, it is still extremely efficient, because to create the VLA in the first place the compiler has to figure out how much space the VLA will take up. So even if not a compile-time constant for a VLA, it is still the most efficient way possible to determine an array size.