A pure C99 solution:
enum { must_be_an_array_1 = ((void *) &(arr)) == ((void *) (arr)) };
typedef char must_be_an_array_2[((void *) &(arr)) == ((void *) (arr)) ? 1 : -1];
This exploits the fact that the address of an array is the same as the address of its first member, and that an enum member must be an integral constant. If the compiler is smart enough to tell that a pointer-to-a-pointer has a distinct address, it will choke on the second statement.
We still need the first statement because otherwise a compiler with support for runtime sized arrays (e.g. gcc 4.7) will perform the address comparison at runtime and invoke undefined behaviour as the size of the runtime array is negative (e.g. under gcc the program segfaults).
Full program:
#include
#define CLEAN_ARRAY(arr) \
do { \
enum { must_be_an_array_1 = ((void *) &(arr)) == ((void *) (arr)) }; \
typedef char must_be_an_array_2[((void *) &(arr)) == ((void *) (arr)) ? 1 : -1]; \
bzero(arr, sizeof(arr)); \
} while (0)
int main() {
int arr[5];
CLEAN_ARRAY(arr);
int *ptr;
CLEAN_ARRAY(ptr); // error: enumerator value for ‘must_be_an_array’ is not an integer constant
return 0;
}