Вот одно возможное решение, использующее расширение GNU, выраженное выражением оператора : :
#define ARRAYSIZE(arr) \
({typedef char ARRAYSIZE_CANT_BE_USED_ON_POINTERS[sizeof(arr) == sizeof(void*) ? -1 : 1]; \
sizeof(arr) / sizeof((arr)[0]);})
Это использует статическое утверждение , чтобы утверждать, что sizeof(arr) != sizeof(void*)
, У этого есть очевидное ограничение - вы не можете использовать этот макрос на массивах, размер которых является точно одним указателем (например, массив длиной 1 строки указателей / целых чисел или, возможно, массив длиной 4 длины в 32-битном Платформа). Но эти конкретные примеры могут быть легко обработаны.
Это решение не переносится на платформы, которые не поддерживают это расширение GNU. В таких случаях я бы рекомендовал просто использовать стандартный макрос и не беспокоиться о случайном прохождении указателей к макросу.