Re: [Boost-bugs] [Boost C++ Libraries] #11835: boost::has_trivial_copy is incorrect on Clang

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #11835: boost::has_trivial_copy is incorrect on Clang
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-12-13 12:03:32


#11835: boost::has_trivial_copy is incorrect on Clang
-------------------------+-------------------------------------------------
  Reporter: | Owner: johnmaddock
  joseph.thomson@… | Status: closed
      Type: Bugs | Component: type_traits
 Milestone: To Be | Severity: Problem
  Determined | Keywords: has_trivial_copy clang memcpy
   Version: Boost | is_trivially_copyable
  1.59.0 |
Resolution: wontfix |
-------------------------+-------------------------------------------------

Comment (by johnmaddock):

> has_trivial_copy and its related traits do not adhere to your
 definition of "trivial" on some compilers.

 I just checked them all with gcc 4.6.4, 4.7.4, 4.8.4, 4.9.2, 5.1.0, plus
 clang and Intel and they all do the correct thing - which is to say they
 all regard deleted operators as non-trivial. This is in 1.60 beta BTW.
 Also verified our tests check this. Note that all these traits have been
 completely rewritten for the next release.

> The documentation for these traits says that they can be used to check
 whether memcpy is safe to use; this is incorrect, as is_trivially_copyable
 is the required condition.

 We have never provided is_trivially_copyable, if we did it would likely be
 composed from these traits. Plus I believe you have this backwards -
 is_trivially_copy_constructible is the std trait - and there is a
 precondition on that trait that the type be copy-constructible, from
 C++14:

 "For a referenceable type T, the same result as
 is_trivially_constructible<T, const T&>::value, otherwise false."

 and then is_trivially_constructible says:

 "is_constructible<T, Args...>::value is true and the variable definition
 for is_constructible, as defined below, is known to call no operation that
 is not trivial ( 3.9, 12)."

 Which would rule out types with deleted copy-constructors from being
 trivially-copyable.

> Your preferred definition of "trivial" is too conservative, and will
 result in some obviously memcpy-able types reporting false for
 is_trivially_copyable.

 Such as? Note that has_trivial_copy (which I accept is badly named)
 refers only to copy-constructors. In your example:
 {{{
 struct X
 {
     const int val;
 };
 }}}

 If you care at all about const-correctness (and you should) then such a
 type really is non-trivial, or more specifically:
 {{{
 default construct trivial
 copy-construct trivial
 move-construct trivial
 destruct trivial
 copy-assign not trivial or allowed
 move-assign not trivial or allowed
 }}}

 Which I believe is what 1.60 has implemented.

> The current standard definition of is_trivially_copyable is potentially
 dangerous when types use certain OS-level resources; a pending amendment
 to the standard fixes this.

 Right, IMO code should use traits which pertain to the actual operation
 that will be performed - for example boost::has_trivial_copy is closest to
 std::is_trivially_copy_constructible and both should return false for non-
 copyable types and avoid that nasty (and very real) black hole.

 One final point: has_trivial_copy and friends were developed for C++03
 (and later included in TR1 standard). There's a lot of code out there
 which relies on has_trivial_copy implies safe-to-memcpy instead of copy
 construct. That code should absolutely not be broken just because C++11
 has introduced new features: ie deleted functions.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/11835#comment:6>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:19 UTC