25

With the introduction of c++11, trivially copyableness has gotten quite relevant. Most notably in the use of 'std::atomic'. The basics are quite simple. A class foo is trivially copyable if:

foo* src = new foo();
foo* dest = malloc(sizeof(foo));
memcpy(dest, src, sizeof(foo));

Has the same effect as:

foo* src = new foo();
foo* dest = new foo(src);

So an object where copying the memory will have the same effect as a copy constructor. However there, of course, is a catch. There's not only copy constructors. But also move constructors, move assignment operators. Etc.

std::is_trivially_copyable can be used to test whether an object is trivially copyable. So with trial and error it is possible to make an object trivially copyable.

But of course a well defined set of rules would be a bit nicer:). So hereby my request.

talonmies
  • 70,661
  • 34
  • 192
  • 269
laurisvr
  • 2,724
  • 6
  • 25
  • 44
  • Your two snippets have not the same effect since one constructs the object while the other does not. Containers of the standard library use memcpy for copy construction only if the type is trivial (trivially copyable + trivially constructible). When the type is only trivially copyable, the copy constructor is used for uninitialized ranges and memcpy for already constructed ranges. Certain operations do use both such as std::vector's assignment. – PixelRick May 28 '19 at 01:04
  • 1
    If you want to make sure that some type is trivially copyable, you can add `static_assert(std::is_trivially_copyable::value);`. Similarly, for some object, you can add `static_assert(std::is_trivially_copyable::value);`. – Sourav Kannantha B Feb 14 '23 at 07:34

1 Answers1

34

The most well-defined set of rules would come directly from the standard. Here are the relevant entries from standard draft N4296:

Trivially-copyable types are defined in [basic.types]/9

Cv-unqualified scalar types, trivially copyable class types, arrays of such types, and nonvolatile const-qualified versions of these types are collectively called trivially copyable types.

Trivially-copyable classes are defined in [class]/6

A trivially copyable class is a class that: has no non-trivial copy constructors, has no non-trivial move constructors, has no non-trivial copy assignment operators, has no non-trivial move assignment operators, and has a trivial destructor.

Copy/move constructors in [class.copy]/12

A copy/move constructor for class X is trivial if it is not user-provided, its parameter-type-list is equivalent to the parameter-type-list of an implicit declaration, and if class X has no virtual functions and no virtual base classes, and class X has no non-static data members of volatile-qualified type, and the constructor selected to copy/move each direct base class subobject is trivial, and for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial; otherwise the copy/move constructor is non-trivial.

Copy/move assignment operators in [class.copy]/25

A copy/move assignment operator for class X is trivial if it is not user-provided, its parameter-type-list is equivalent to the parameter-type-list of an implicit declaration, and if class X has no virtual functions and no virtual base classes, and class X has no non-static data members of volatile-qualified type, and the assignment operator selected to copy/move each direct base class subobject is trivial, and for each non-static data member of X that is of class type (or array thereof), the assignment operator selected to copy/move that member is trivial; otherwise the copy/move assignment operator is non-trivial.

Destructors in [class.dtor]/5

A destructor is trivial if it is not user-provided and if: the destructor is not virtual, all of the direct base classes of its class have trivial destructors, for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor. Otherwise, the destructor is non-trivial.

User-provided constructors in [dcl.fct.def.default]/5

Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them (12.1 12.4, 12.8), which might mean defining them as deleted. A function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed.

The short answer is that the short answer is sometimes more helpful than the long answer.

TartanLlama
  • 63,752
  • 13
  • 157
  • 193