[cfe-users] __builtin_constant_p(), __builtin_expect() and __builtin_types_compatible_p() and __has_builtin()
Richard Smith via cfe-users
cfe-users at lists.llvm.org
Fri Aug 9 14:58:50 PDT 2019
On Fri, 9 Aug 2019 at 10:32, Chris Hall via cfe-users <
cfe-users at lists.llvm.org> wrote:
> On 09/08/2019 15:00, Matthew Fernandez wrote:
> >> On Aug 9, 2019, at 05:23, Chris Hall via cfe-users wrote:
> >>
> >> I find that __builtin_constant_p() works as expected, but
> >> __has_builtin(constant_p) denies it !
>
> > I believe you need __has_builtin(__builtin_constant_p).
>
> Ah :-( So you do... sorry... I have no idea why I thought otherwise :-(
>
> >> Similarly __builtin_expect() and __builtin_types_compatible_p() !
>
> Except that __has_builtin(__builtin_types_compatible_p) also denies it.
>
> #include <stdio.h>
>
> int
> main(int argc, char* argv[])
> {
> printf("__has_builtin(__builtin_types_compatible_p)=%d\n"
> "__builtin_types_compatible_p(int, int)=%d\n"
> "__builtin_types_compatible_p(int, long)=%d\n",
> __has_builtin(__builtin_types_compatible_p),
> __builtin_types_compatible_p(int, int),
> __builtin_types_compatible_p(int, long)) ;
> }
>
> outputs:
>
> __has_builtin(__builtin_types_compatible_p)=0
> __builtin_types_compatible_p(int, int)=1
> __builtin_types_compatible_p(int, long)=0
>
> I hope I haven't missed something blindingly obvious this time.
>
This is a historical accident.
__has_builtin detects builtin *functions*. We also have a bunch of things
that start with __builtin and look somewhat like functions, but that take
types as arguments so can't actually be functions -- instead, they're
keywords with custom parsing rules. __has_builtin doesn't detect those
(because they're not builtin functions).
We've fixed this for such things we added recently, such as
__builtin_bit_cast and __builtin_FILE, but the older ones like
__builtin_types_compatible_p and __builtin_choose_expr and
__builtin_offsetof are unfortunately not detectable by __has_builtin.
There is another way to detect these: use
!__is_identifier(__builtin_types_compatible_p). That will evaluate to 1
whenever __builtin_types_compatible_p is not a valid identifier (because
it's a keyword) -- that is, whenever the feature is available. However,
__is_identifier was added in April 2014, and nearly all the builtins that
__has_builtin can't detect are older than that. So this technique isn't
really useful.
In practice, every version of Clang from the past 10 years supports
__builtin_types_compatible_p (in C mode). So you can just assume it exists.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-users/attachments/20190809/97d5fc4e/attachment.html>
More information about the cfe-users
mailing list