strNOcat
strNOcat

Reputation: 923

Clang's __has_builtin doesn't always work

With respect to the following test code, the expected outcome was that it wouldn't compile because of the #error directive.

#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;
}

However, not only it compiles but it also prints out INT ARE SAME!!! which means that even though __builtin_types_compatible_p exists, __has_builtin is not detecting it. Why is it? And more importantly, is there some other way to detect for built-in functions that will work?

This was tested on Clang 3.8 and 3.9 (the current stable branch). The code was compiled using clang --std=c99 -Wall -Wextra test.c.

Upvotes: 3

Views: 2927

Answers (2)

ktns
ktns

Reputation: 54

Note: This answer is outdated as of Clang 10.


According to a LLVM developer,

__has_builtin detects builtin functions.

In your example, __builtin_types_compatible_p is

not a function at all, since it takes a type, not a value.

So, __has_builtin(__builtin_types_compatible_p) returns false, which is exactly as designed.

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

Upvotes: 3

dumbass
dumbass

Reputation: 27222

Before Clang 10, __has_builtin only recognised built-in functions. Constructs like __builtin_types_compatible_p that take type arguments are not functions, but keywords with usage syntax somewhat resembling functions – similar to sizeof. Clang 10 changed the behaviour of __has_builtin so that certain function-like keywords are recognised as built-ins. However, built-ins that are neither functions nor keywords (like the type __builtin_va_list) are still not recognised as of Clang 11.

If you need to check for the presence of a function-like keyword in older versions of Clang, use !__is_identifier(). Alternatively, you can search for an argument to __has_extension or __has_feature that covers the feature.

GCC's implementation of __has_builtin has supported function-like keywords from the start; it was added in GCC 10.

Upvotes: 4

Related Questions