Subject: [Boost-bugs] [Boost C++ Libraries] #11835: boost::has_trivial_copy is incorrect on Clang
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-12-09 09:26:39
#11835: boost::has_trivial_copy is incorrect on Clang
-------------------------------------------------+-------------------------
Reporter: joseph.thomson@⦠| Owner: johnmaddock
Type: Bugs | Status: new
Milestone: To Be Determined | Component: type_traits
Version: Boost 1.59.0 | Severity: Problem
Keywords: has_trivial_copy clang memcpy |
is_trivially_copyable |
-------------------------------------------------+-------------------------
Currently, `boost::has_trivial_copy<T>::value` is false when `T` has a
trivial copy constructor, but is uncopyable. For example, the following
type, despite having a trivial copy constructor, will report false:
{{{
struct T {
T(T const&) = delete;
}
}}}
The offending code seems to be:
{{{
template <typename T>
struct has_trivial_copy_impl
{
#ifdef BOOST_HAS_TRIVIAL_COPY
# ifdef __clang__
BOOST_STATIC_CONSTANT(bool, value = BOOST_HAS_TRIVIAL_COPY(T) &&
boost::is_copy_constructible<T>::value);
# else
BOOST_STATIC_CONSTANT(bool, value = BOOST_HAS_TRIVIAL_COPY(T));
# endif
#else
BOOST_STATIC_CONSTANT(bool, value =
(::boost::type_traits::ice_and<
::boost::is_pod<T>::value,
::boost::type_traits::ice_not< ::boost::is_volatile<T>::value
>::value
>::value));
#endif
};
}}}
This fix was applied for Clang for the following ticket:
https://svn.boost.org/trac/boost/ticket/10389
The fix actually broke the behaviour of `boost::has_trivial_copy` in
Clang, to make it match the broken behaviour in GCC 4.8 and VC++. The bug
was actually in Boost.Container, not Boost.TypeTraits, but that bug has
now been fixed (Boost.Container no longer depends on Boost.TypeTraits).
GCC actually fixed its intrinsic `__has_trivial_copy` in GCC 4.9, so
`boost::has_trivial_copy` works correctly in the latest GCC versions. It's
still broken on VC++ because of its faulty implementation of
`__has_trivial_copy`, though it seems probable that there is no possible
workaround.
But I digress. `__has_trivial_copy` works on Clang, but the "fix" in Boost
breaks `boost::has_trivial_copy`. Note that `boost::has_trivial_assign`,
`boost::has_trivial_move_constructor` and `boost::has_trivial_move_assign`
appear to be okay.
And one final thought: `boost::has_trivial_copy` is not really useful for
anything except implementing higher-level type-traits like
`std::is_trivially_copyable` (which essentially says whether a type can be
safely `memcpy`'d -- a copy optimization).
`std::has_trivial_copy_constructor` does not exist, probably for this
reason. In my opinion, it would be better for `boost::has_trivial_copy` to
not exist in the public API, instead replacing it with a
`boost::is_trivially_copyable`.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/11835> 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