On Fri, 9 Aug 2019 at 10:32, Chris Hall via cfe-users < cfe-users@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.
_______________________________________________ cfe-users mailing list cfe-users@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-users