__builtin_types_compatible_p(t1, t2) 和指向限定类型​​的指针

__builtin_types_compatible_p(t1, t2) and pointers to qualified types

gcc 文档说 __builtin_types_compatible_p(t1, t2)“忽略顶级限定符(例如 const、volatile)”,确实如此:

__builtin_types_compatible_p(int, const int)     returns 1
__builtin_types_compatible_p(int, volatile int)  also returns 1

我不知道“顶级限定符”是什么意思,但是指向兼容事物的指针被报告为兼容:

__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

坦率地说,这是一个惊喜:-(

任何人都可以提供一个原因吗? [我的惊讶是无知的表现吗?]


FWIW:我可以使用 __typeof__() 解决此问题,因此:

__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

由于__typeof__()接受表达式和类型,我有一个宏:

#define Types_Compatible(_a, _b) \
  __builtin_types_compatible_p(__typeof__(_a), __typeof__(_b)) 

稍微减少混乱。

intconst int 是兼容的,因为在任何需要 int 的地方(例如作为函数参数)都可以给出 const int。而且,重要的是,反之亦然。 constvolatile 只影响变量,不影响值。

不是 int*const int* 的情况。如果函数需要 int*,您可以 而不是 提供 const int*。如果您尝试这样做,您将收到 'incompatible types' 错误。对于指针,constvolatile 指的是 ,而不是变量。 (在大多数情况下,这取决于您放置 const 的位置)

而您的“解决方法”只是取消对指针的引用,因此它摆脱了指针,因此它最终回答了一个不同的问题。它判断指向的类型是否兼容,这与指针类型本身不同。

在我看来,类型 T1 与类型 T2 兼容意味着当您有两个变量 T1 a 和 T2 b 时,您可以分配 a = b 并同时分配 b = a。