The gcc documentation says that __builtin_types_compatible_p(t1, t2)
"ignores top level qualifiers (e.g. const, volatile)", and indeed it does:
__builtin_types_compatible_p(int, const int) returns 1
__builtin_types_compatible_p(int, volatile int) also returns 1
I do not know what it means by "top level qualifiers", but pointers to things-which-are-compatible, are reported as not compatible:
__builtin_types_compatible_p(int *, const int *) returns 0
__builtin_types_compatible_p(int *, volatile int *) also returns 0
__builtin_types_compatible_p(void *, void *) returns 1
__builtin_types_compatible_p(void *, const void *) returns 0
which is, frankly, a surprise :-(
Can anyone provide a reason for this ? [Is my surprise a symptom of ignorance ?]
FWIW: I can work around this using __typeof__()
, thus:
__builtin_types_compatible_p(__typeof__(*(void*)0), __typeof__(*(const void*)0))) returns 1
typedef int* pi_t ;
typedef const int* pic_t ;
__builtin_types_compatible_p(__typeof__(*(pi_t)0), __typeof__(*(pic_t)0))) returns 1
Since __typeof__()
accepts both an expression and a type, I have a macro:
#define Types_Compatible(_a, _b) \
__builtin_types_compatible_p(__typeof__(_a), __typeof__(_b))
to slightly reduce the clutter.