Opened 7 years ago
Closed 6 years ago
#11844 closed Bugs (fixed)
memcpy should only be used on trivially copyable objects
Reported by: | Owned by: | Ion Gaztañaga | |
---|---|---|---|
Milestone: | To Be Determined | Component: | container |
Version: | Boost 1.60.0 | Severity: | Problem |
Keywords: | Cc: |
Description
This is a follow up to this ticket:
https://svn.boost.org/trac/boost/ticket/11229
Boost.Container currently checks the is_trivially_copy_constructible
and is_trivially_copy_assignable
type traits to enable memcpy
optimization. However, the standard says that memcpy
may only be used with trivially copyable types, and being trivially copy constructible/assignable is not a sufficient, or indeed necessary, condition for trivial copyability. Trivially copyable types must:
- Have no non-trivial copy constructors
- Have no non-trivial copy assignment operators
- Have no non-trivial move constructors
- Have no non-trivial move assignment operators
- Have a trivial destructor
Note that deleted special functions are classified as trivial. This is required, otherwise types such as this would not be trivially copyable:
struct X { const int x; };
This is why I say that trivially copy constructibility is not a necessary condition for trivial copyability.
Note that there is a proposal to modify the definition of trivially copyable so that at least one special function has to not be deleted (and the destructor must not be deleted):
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4460.html
Using memcpy
with types that aren't trivially copyable is undefined behaviour according to the standard. Thus, the behaviour of Boost.Container is technically undefined when used with types that are trivially copy constructible/assignable but not trivially copyable.
Thanks for the report, as mentioned in the related ticket, the library now checks is a type is copy constructible or copy assignable to implement its internal "is_trivially_copy_assignable" and "is_trivially_copy_constructible" types. Commited in:
https://github.com/boostorg/move/commit/e7d24400cb986efaefa0acbff5de6e74eae876d9