3

对于下面的测试代码,预期的结果是它不会因为#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

4

2 回答 2

3

注意:这个答案在 Clang 10 中已经过时了。


根据 LLVM 开发人员的说法,

__has_builtin 检测内置函数。

在您的示例中, __builtin_types_compatible_p 是

根本不是一个函数,因为它需要一个类型,而不是一个值。

因此,__has_builtin(__builtin_types_compatible_p)返回 false,这完全符合设计。

http://lists.llvm.org/pipermail/cfe-dev/2017-July/054590.html

于 2017-07-11T19:36:01.220 回答
2

在 Clang 10 之前,__has_builtin只识别内置函数。像__builtin_types_compatible_p这样接受类型参数的构造不是函数,而是使用语法有点类似于函数的关键字——类似于sizeof. Clang 10改变了 的行为,__has_builtin以便某些类似函数的关键字被识别为内置。但是,从 Clang 11 开始,既不是函数也不是关键字的内置函数(如 type __builtin_va_list)仍然无法识别。

如果您需要检查旧版本 Clang 中是否存在类似函数的关键字,请使用!__is_identifier(). 或者,您可以搜索__has_extension__has_feature涵盖该功能的参数。

GCC 的实现__has_builtin从一开始就支持类似函数的关键字;它是在 GCC 10 中添加的。

于 2019-05-12T15:17:29.947 回答