Clang 的 __has_builtin 并不总是有效
Clang's __has_builtin doesn't always work
对于以下测试代码,预期结果是由于 #error
指令而无法编译。
#if __has_builtin(__builtin_types_compatible_p)
#error ("Hello")
#endif
#include <stdio.h>
int main (void)
{
if (__builtin_types_compatible_p(int, const int)) {
printf("INT ARE SAME!!!\n");
}
return 0;
}
然而,它不仅编译而且还打印出 INT ARE SAME!!!
这意味着即使 __builtin_types_compatible_p
存在,__has_builtin
也没有检测到它。为什么?更重要的是,是否有其他方法可以检测可用的内置函数?
这是在 Clang 3.8 和 3.9(当前的稳定分支)上测试的。代码是使用 clang --std=c99 -Wall -Wextra test.c
.
编译的
注意:自 Clang 10 起,此答案已过时。
根据 LLVM 开发人员的说法,
__has_builtin detects builtin functions.
在您的示例中,__builtin_types_compatible_p 是
not a function at all, since it takes a type, not a value.
所以,__has_builtin(__builtin_types_compatible_p)
returns false,完全符合设计。
http://lists.llvm.org/pipermail/cfe-dev/2017-July/054590.html
在 Clang 10 之前,__has_builtin
只能识别 built-in 函数。像 __builtin_types_compatible_p
这样接受类型参数的构造不是函数,而是使用语法 有点 类似于函数的关键字——类似于 sizeof
。 Clang 10 changed the behaviour of __has_builtin
以便某些 function-like 关键字被识别为 built-in。但是,从 Clang 11 开始,仍然无法识别既不是函数也不是关键字的 built-in(例如 __builtin_va_list
类型)。
如果您需要检查旧版本的 Clang 中是否存在 function-like 关键字,请使用包含该功能的 !__is_identifier()
. Alternatively, you can search for an argument to __has_extension
or __has_feature
。
GCC's implementation of __has_builtin
从一开始就支持 function-like 个关键字;它是在 GCC 10 中添加的。
对于以下测试代码,预期结果是由于 #error
指令而无法编译。
#if __has_builtin(__builtin_types_compatible_p)
#error ("Hello")
#endif
#include <stdio.h>
int main (void)
{
if (__builtin_types_compatible_p(int, const int)) {
printf("INT ARE SAME!!!\n");
}
return 0;
}
然而,它不仅编译而且还打印出 INT ARE SAME!!!
这意味着即使 __builtin_types_compatible_p
存在,__has_builtin
也没有检测到它。为什么?更重要的是,是否有其他方法可以检测可用的内置函数?
这是在 Clang 3.8 和 3.9(当前的稳定分支)上测试的。代码是使用 clang --std=c99 -Wall -Wextra test.c
.
注意:自 Clang 10 起,此答案已过时。
根据 LLVM 开发人员的说法,
__has_builtin detects builtin functions.
在您的示例中,__builtin_types_compatible_p 是
not a function at all, since it takes a type, not a value.
所以,__has_builtin(__builtin_types_compatible_p)
returns false,完全符合设计。
http://lists.llvm.org/pipermail/cfe-dev/2017-July/054590.html
在 Clang 10 之前,__has_builtin
只能识别 built-in 函数。像 __builtin_types_compatible_p
这样接受类型参数的构造不是函数,而是使用语法 有点 类似于函数的关键字——类似于 sizeof
。 Clang 10 changed the behaviour of __has_builtin
以便某些 function-like 关键字被识别为 built-in。但是,从 Clang 11 开始,仍然无法识别既不是函数也不是关键字的 built-in(例如 __builtin_va_list
类型)。
如果您需要检查旧版本的 Clang 中是否存在 function-like 关键字,请使用包含该功能的 !__is_identifier()
. Alternatively, you can search for an argument to __has_extension
or __has_feature
。
GCC's implementation of __has_builtin
从一开始就支持 function-like 个关键字;它是在 GCC 10 中添加的。