Opened 7 years ago

Closed 6 years ago

#11844 closed Bugs (fixed)

memcpy should only be used on trivially copyable objects

Reported by: joseph.thomson@… 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.

Change History (1)

comment:1 by Ion Gaztañaga, 6 years ago

Resolution: fixed
Status: newclosed

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

Note: See TracTickets for help on using tickets.