The file include/linux/typecheck.h
of the Linux kernel 4.16 contains this code.
#define typecheck(type,x) \\
({ type __dummy; \\
ty
This uses two GCC extensions — expression statements ({ ... })
and typeof()
.
type
.x
.-Werror
).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
Comparing pointers with incompatible types is a constraint violation and requires the compiler to issue a diagnostic. See 6.5.9 Equality operators:
Constraints
One of the following shall hold:
- both operands have arithmetic type;
- both operands are pointers to qualified or unqualified versions of compatible types;
- one operand is a pointer to an object or incomplete type and the other is a pointer to a qualified or unqualified version of void; or
- one operand is a pointer and the other is a null pointer constant.
and 5.1.1.3 Diagnostics:
A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.