Skip to content

Instantly share code, notes, and snippets.

@mchouza mchouza/explanation.md Secret
Last active Aug 29, 2015

Embed
What would you like to do?
Explanation of the array type checking

The basic idea is to call a function pointer receiving a pointer to an array of the desired type with a pointer to the parameter. As we don't know the base type of the array we can use the commonly provided extension __typeof__ to get it. Then we can use the "normal" ASIZE() to get its size and a pointer to that type will be defined by

#define GET_COMPATIBLE_ARRAY_PTR_TYPE( a ) __typeof__((a)[0])(*)[ASIZE(a)]

Now we define the type of a function pointer taking that array pointer type as a parameter and returning void:

#define GET_CHECKING_FUNC_PTR_TYPE( a ) void (*)(GET_COMPATIBLE_ARRAY_PTR_TYPE( a ))

We can then cast a NULL pointer to that function pointer type and call it with a pointer to the argument:

#define CHECK_ARRAY_SEGFAULT( a ) ((GET_CHECKING_FUNC_PTR_TYPE( a ))NULL)(&(a))

That code "works", in the sense of compiling when a is an array and failing to compile otherwise... but it gives us a segmentation fault when executed. We can solve that by using the short-circuiting behavior of boolean operators and adding a cast to void to avoid compiler warnings:

#define GET_CHECKING_FUNC_PTR_TYPE( a ) (int (*)(GET_COMPATIBLE_ARRAY_PTR_TYPE( a )))
#define CHECK_ARRAY(a) ((void)(0&&((GET_CHECKING_FUNC_PTR_TYPE( a ))NULL)(&(a))))

This version compiles & executes correctly. The presented version is just the (almost) fully substituted version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.