In C11 you could use _Static_assert
in conjunction with _Generic
, but you'll also need to provide type info, which I see as a good thing as it provides extra granularity; you get the ability to assert based on element type, as well as whether it's an array or not from _Generic
, and you get a nice friendly message from _Static_assert
... For example:
assert_array_type.c:6:33: error: static assertion failed: "expected array of int; got (char[42]){0}"
assert_array_type.c:6:33: error: static assertion failed: "expected array of int; got (int *){0}"
These errors are produced by the following testcase, depending upon how you compile:
#define array_type(a, T) _Generic(a, T *: _Generic(&a, T **: 0 \
, default: 1)\
, default: 0)
#define assert_array_type(a, T) _Static_assert(array_type(a, T), "expected array of " #T "; got " #a)
int main(void) {
assert_array_type((int [42]){0}, int); // this should pass
# if defined(TEST_POINTER_FAIL)
assert_array_type((int * ){0}, int); // this should fail
# endif
# if defined(TEST_ELEMENT_FAIL)
assert_array_type((char[42]){0}, int); // this should fail
# endif
}
The two testcases can observed by defining TEST_POINTER_FAIL
and/or TEST_ELEMENT_FAIL
, i.e.
cc -std=c11 -D'TEST_POINTER_FAIL'
should cause an assertion failure at compilation time due to the fact that a pointer is passed, rather than an array.
cc -std=c11 -D'TEST_ELEMENT_FAIL'
should cause an assertion failure at compilation time due to the fact that the array is meant to be an array of int
, rather than an array of char
.