This uses two GCC extensions — expression statements ({ ... })
and typeof()
.
- The first line of the expansion declares a variable of the named type
type
.
- The second line of the expansion declares a variable of the same type as the variable or expression
x
.
- The third line compares the two pointers, which will only match if the types of the two dummy variables match, generating a pointer mismatch warning (or error if compiling with
-Werror
).
- The last line (containing the
1
) is the value of the expression — equivalent to true.
So, you get a compilation warning/error if the type of x
is not the same as the named type.
Example code:
#include <stdio.h>
#define typecheck(type,x) \
({ type __dummy; \
typeof(x) __dummy2; \
(void)(&__dummy == &__dummy2); \
1; \
})
int main(void)
{
int x;
if (typecheck(int, x))
printf("int x OK\n");
if (typecheck(double, x))
printf("double x OK\n");
return(0);
}
Compilation message:
$ /usr/bin/gcc -O3 -g -std=gnu99 -Wall -Wextra xx.c -o xx
xx.c: In function ‘main’:
xx.c:15: warning: comparison of distinct pointer types lacks a cast
$
Note that because I did not use -Werror
, the code compiled 'OK'. The output was:
int x OK
double x OK