[cfe-dev] Keyword warnings in libc++'s type_traits and other headers
Alp Toker
alp at nuanti.com
Mon Dec 23 17:28:34 PST 2013
On 24/12/2013 00:29, Marshall Clow wrote:
> On Dec 23, 2013, at 1:16 PM, Howard Hinnant <howard.hinnant at gmail.com
> <mailto:howard.hinnant at gmail.com>> wrote:
>>
>> Two further questions:
>>
>> 1. Do these keywords come with __has_feature tests (like __is_class
>> does)? If not, they should.
>>
>> 2. If they do come with __has_feature tests, how about libc++ doing
>> the same thing it does for is_class et al.?
>>
>> #if !__has_feature(is_void)
>>
>> template <class _Tp> struct __is_void : public false_type {};
>> template <> struct __is_void<void> : public true_type {};
>>
>> #endif // !__has_feature(is_void)
>>
>> template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_void
>> : public __is_void<typename remove_cv<_Tp>::type> {};
>>
>> That way we don't need major surgery. We avoid the conflict if it
>> exists. And we take advantage of the compiler intrinsic if it exists.
>
> This sounds good to me, but I think it’ll be a bit more involved than
> that:
>
> #if !__has_feature(is_void)
Hi Marshall,
A feature definition was never added for these trait intrinsics
unfortunately. I'll look into it.
>
> template <class _Tp> struct __is_void : public false_type {};
> template <> struct __is_void<void> : public true_type {};
>
> template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_void
> : public __is_void<typename remove_cv<_Tp>::type> {};
This would still conflict with the keyword in current clang versions and
other compilers that don't have a quality __has_feature() implementation.
To reiterate, you'll do well to avoid the __is_* prefix entirely
regardless of whether you can feature-test for individual availability
of the keywords.
I'll try to illustrate this in a different way, taking clang out of the
picture for a minute. None of these structures extracted from libc++
will compile with MSVC 2013:
|struct __is_nothrow_constructible {}||;||
||testvc.cpp(8) : error C2332: 'struct' : missing tag name||
||||
||struct __is_nothrow_assignable||{}||;||
||testvc.cpp(8) : error C2332: 'struct' : missing tag name||
||||
||struct __is_constructible {}||;||
||testvc.cpp(8) : error C2332: 'struct' : missing tag name|
It's a fact of life that there many compiler-defined keywords littering
the __is_* namespace and most of them are undocumented. Trying to use
them as identifiers or type names is a parse error.
You /could/ try to continue using the __is_* names that are known not to
conflict today, but it's a quixotic solution that'll break every time a
new compiler point-release adds new built-in trait primitives.
>
> #else
>
> template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_void
> : public integral_constant<bool, __is_void(typename
> remove_cv<_Tp>::type)>;
>
> #endif // !__has_feature(is_void)
This part will work.
I'd actually recommend keeping the production-quality library
implementations in libc++ instead of switching wholesale to the clang
intrinsics. Many of our intrinsics are there for compatibility and
haven't been fully tested in a production environment.
If you just s/__is_/__libcpp_is_/ to avoid the keywords you'll gain
compatibility with other modern compilers, silence the extension
warnings and help us set a schedule for removing the GNU compatibility
hack in the parser.
After that we can start to look at offering optimized type traits by
coordinating more closely, but it's not the immediate issue at hand.
Alp.
--
http://www.nuanti.com
the browser experts
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131224/d9cc7aef/attachment.html>
More information about the cfe-dev
mailing list