【问题标题】:Clang's __has_builtin doesn't always workClang 的 __has_builtin 并不总是有效
【发布时间】:2017-08-02 08:02:55
【问题描述】:

对于下面的测试代码,预期的结果是由于#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编译。

【问题讨论】:

    标签: c clang c99 built-in clang-extensions


    【解决方案1】:

    注意:这个答案在 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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2012-12-26
        • 1970-01-01
        • 1970-01-01
        • 2012-04-23
        • 2015-06-28
        • 2015-12-04
        • 2017-01-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多