Reputation: 923
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
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
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