Поиск размера статического массива - обычная операция. см. C найдите размер статического массива - sizeof(a) / sizeof((a)[0])
Это может быть завернуто в макрос, например:
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
однако его можно случайно передать обычным указателем.
например: void func(SomeArray **foo) { int i = ARRAY_SIZE(foo); }
Пока он действительный C, но часто заканчивается логической ошибкой.
Возможно предотвратить эту ошибку (используя преимущество каждого процессора для отказа в битовом поле нулевой длины).
#define ARRAY_SIZE(a) \
((sizeof(struct { int isnt_array : \
((const void *)&(a) == &(a)[0]); }) * 0) + \
(sizeof(a) / sizeof(*(a))))
Я нашел, что этот макрос работает с GCC, но не работает с Clang, для косвенно связанных членов. с error: expression is not an integer constant expression
например:
-
char word[8]; int i = ARRAY_SIZE(word);
ok. -
struct Bar { word[8]; }
void func(struct Bar *foo) { int i = ARRAY_SIZE(foo->word); }
не работает.
Есть ли более переносимый способ реализовать это? (работа с Clang хороша, конечно, хотя я заинтересован в общей переносимости... других компиляторов тоже).
Это кажется такой общей задачей, что было бы неплохо иметь повторно используемый портативный макрос.