[cfe-dev] The state of clang type traits

Douglas Gregor dgregor at apple.com
Wed May 11 17:05:12 PDT 2011


On May 11, 2011, at 8:36 AM, Howard Hinnant wrote:

> On May 9, 2011, at 3:27 PM, Howard Hinnant wrote:
> 
>> Good work has been done on the clang type traits since the last time I did a survey.  I wanted to re-do the survey based on the good clang documentation at:
>> 
>> http://clang.llvm.org/docs/LanguageExtensions.html#checking_type_traits
>> 
>> I've put the updated results here:
>> 
>> http://libcxx.llvm.org/type_traits_design.html
>> 
>> The big needs are shown in the boxes with the red background.  The "nothrow" traits are especially needed in light of the recent work done for noexcept.  From the client's point of view, the only behavior change a noexcept spec gives to a member function is whether or not the associated is_nothrow_ trait returns true or not.  We currently can not detect nothrow destructors, nothrow constructors other than the default and copy constructors, nor nothrow assignment operators other than the copy assignment operator.
>> 
>> Three of the traits I can do in the library if CWG 1170 is implemented:
>> 
>> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1170
>> 
>> This is the one where access checks should be done as part of the substitution process.  However I'd be happier with compiler type traits for those three.
> 
> I've learned that if CWG 1170 is implemented, I can also do library implementations of all of the nothrow traits by putting expressions into noexcept.  For example:
> 
> // is_nothrow_destructible
> 
> template <bool, class _Tp> struct __is_nothrow_destructible;
> 
> template <class _Tp>
> struct __is_nothrow_destructible<false, _Tp>
>    : public false_type
> {
> };
> 
> template <class _Tp>
> struct __is_nothrow_destructible<true, _Tp>
>    : public integral_constant<bool, noexcept(_STD::declval<_Tp>().~_Tp()) >
> {
> };
> 
> template <class _Tp>
> struct is_nothrow_destructible
>    : public __is_nothrow_destructible<is_destructible<_Tp>::value, _Tp>
> {
> };
> 
> This reduces the highest priority needs for clang type trait support to:
> 
> 1.  Implement CWG 1170

Done in Clang r131209.

> 2. __is_trivially_constructible(T, Args...)
> 3. __is_trivially_assignable(T, U)

Interesting. I don't know what a "trivial operation" is, but I suspect that this means something like "no calls to anything that isn't a trivial constructor (in the first case) or a trivial assignment operator (in the second case)".

> 4. __is_trivial(T)

This is already implemented in mainline.

> 5. __is_trivially_copyable(T)

Should be "trivial", since the Clang AST already exposes this information.

> 6. __is_standard_layout(T)

This is already implemented on mainline.

> 7. __underlying_type(T)

Interesting. The C++0x std::underlying_type is only defined for enumeration types. However, the various character types (wchar_t, char16_t, char32_t) also have underlying types. I suggest that implement the __underlying_type primitive also do the right thing for the character types.

Note that implementing this one correctly is significantly more difficult than any of the others, since it impacts the type system.

> An alternative to 2-5 is to implement a __trivial(expression) that can be tested similar to noexcept(expression).  This would allow me to use techniques as shown above for is_nothrow_destructible.

… except that I don't know what the a "trivial" expression is. The standard doesn't define this notion at all. I think we should keep our trivial type traits fairly narrow.

	- Doug





More information about the cfe-dev mailing list