[cfe-dev] __has_feature coverage

Alp Toker alp at nuanti.com
Thu May 1 22:36:29 PDT 2014


On 02/05/2014 05:34, Richard Smith wrote:
> IIRC there were concerns that __has_feature might not be the right 
> place to be surfacing these traits.

Right, I took some notes back when I was looking into this and my 
findings were:

__has_feature() is intended for standardised language features and it's 
prominently user-facing so not really appropriate for trait primitives 
whether or not they're feature-complete. Once an alternative is found we 
should phase those out.

__has_extension() also suffers from being user-facing, but perhaps less so.

__has_builtin() would let us automatically list all built-in trait 
primitives and I did some work to support that but it wasn't clear what 
value this adds so I've put that aside.

Observation: There's no need to list "compatibility-only" or poorly 
defined trait primitives in any detection macro because they only exist 
for compatibility with MSVC and GCC which use without checking, with the 
possible exception of Embarcadero(?).

As you see this is a bit of a tangle. As a way forward the viable 
options to provide a feature test for _quality_ type trait primitives 
could be one of:

a) A new __has_primitive()
b) Shoehorning into __has_extension() but naming the features more 
clearly as primitives: e.g. __has_extension(primitive_is_constructible)

>
> Some of the traits don't work in general (and support just enough to 
> get through the MS headers); I don't recall exactly which ones, 
> though, and I think it was more than just __is_*_destructible. Alp, do 
> you recall? (Maybe it was the __is_nothrow_* ones?)

Many of the _is_ ones are sketchy. I cooked up some tests to compare 
them against GCC and while compatibility was good, overall usefulness 
wasn't clear and some of the results were sketchy. I'll see if I can dig 
this up but the results may be lost (wish we had a wiki to throw stuff 
like this).

Meanwhile our tests for the trait primitives have inconsistent coverage 
and fixing them would be a lot of work. Fortunately the libc++ test 
suite has great coverage and it might be possible to reuse that work..

Marshall, do you think a strategically placed static_assert() could be 
added somewhere in your type trait tests to compare answers from the 
clang builtin type trait primitives against your quality library 
implementations?

>
> Do we advertise support for the __has_* ones? We should stop doing 
> that if we do -- they're fundamentally broken and pretty much useless 
> (they exist to support libstdc++ and give wrong answers in some cases 
> for GCC compatibility). Eventually I would ilke to make them synonyms 
> for the correct traits, but I'm concerned that people might be relying 
> on the GCC bugs that we emulate for them.

My understanding of the Embarcadero usage is that they _DO_ use the 
feature detection macros. If this is indeed the case (they should 
comment, do we have a contact?) then removing them from __has_feature() 
is tantamount to removing them completely. I'm not at all opposed to 
that but it should be done after we get the facts from the original authors.

Alp.


>
>
> On Thu, May 1, 2014 at 7:48 AM, Marshall Clow <mclow.lists at gmail.com 
> <mailto:mclow.lists at gmail.com>> wrote:
>
>     Recently, reading llvm/tools/clang/docs/LanguageExtensions.rst, I
>     saw a list of type_trait primitives
>     supported by clang.
>
>     One of them caught my eye: __is_nothrow_constructible  — that
>     could be handy for use in libc++.
>
>     So I ran a quick test:
>
>             __is_nothrow_constructible(int)
>     and it returned true.
>
>     Then I tried:
>             __has_feature(is_nothrow_constructible)
>     and it returned false.
>
>     Well, that’s not useful to me; I need to be able to tell when I
>     can use that feature.
>     So I whipped up a program to test all of the type_traits listed in
>     that file (attached),
>     and to see if I can check (using __has_feature) whether or not
>     they are implemented.
>
>     Turns out that __has_feature returns false for the following type
>     traits:
>
>             __has_feature(is_interface_class) = 0
>             __has_feature(is_destructible) = 0
>             __has_feature(is_nothrow_destructible) = 0
>             __has_feature(is_nothrow_assignable) = 0
>             __has_feature(is_nothrow_constructible) = 0
>
>     __is_interface_class is a MS extension; so that’s fine.
>     __is_destructible and __is_nothrow_destructible are described as
>     “partially implemented”, and attempts to use them fail.
>
>     On the other hand:
>             __is_nothrow_constructible(int) returns 1
>             __is_nothrow_assignable(int&, int) returns 1
>
>     So these two seem to work (for at least one case)
>     It seems to me that we should have feature tests for these type
>     traits if we expect people to use them
>
>     So, I’d like to see
>             __has_feature(is_nothrow_constructible)
>     and     __has_feature(is_nothrow_assignable)
>
>     return 1
>
>
>     — Marshall
>
>
>

-- 
http://www.nuanti.com
the browser experts




More information about the cfe-dev mailing list