Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When is a type in c++11 allowed to be memcpyed?

Tags:

My question is the following:

If I want to copy a class type, memcpy can do it very fast. This is allowed in some situations.

We have some type traits:

  • is_standard_layout.
  • is_trivially_copyable.

What I would like to know is the exact requirements when a type will be "bitwise copyable".

My conclusion is that a type is bitwise copyable if both of is_trivally_copyable and is_standard_layout traits are true:

  1. It is exactly what I need to bitwise copy?
  2. Is it overconstrained?
  3. Is it underconstrained?

P.S.: of course, the result of memcpy must be correct. I know I could memcpy in any situation but incorrectly.

like image 983
Germán Diago Avatar asked Nov 19 '14 04:11

Germán Diago


2 Answers

You can copy an object of type T using memcpy when is_trivially_copyable<T>::value is true. There is no particular need for the type to be a standard layout type. The definition of 'trivially copyable' is essentially that it's safe to do this.

An example of a class that is safe to copy with memcpy but which is not standard layout:

struct T {   int i; private:   int j; }; 

Because this class uses different access control for different non-static data members it is not standard layout, but it is still trivially copyable.

like image 144
bames53 Avatar answered Nov 11 '22 18:11

bames53


If is_trivally_copyable<T>::value (or in C++14 is_trivially_copyable<T>(), or in C++17 is_trivially_copyable_v<T>) is not zero, the type is copyable using memcpy.

Per the C++ standard, a type being trivially copyable means:

the underlying bytes making up the object can be copied into an array of char or unsigned char. If the content of the array of char or unsigned char is copied back into the object, the object shall subsequently hold its original value.

However, it is important to realise that pointers are trivially copyable types, too. Whenever there are pointer inside the data structures you will be copying, you have to brainually make sure that copying them around is proper.

Examples where hazard may be caused by just relying on the object being trivially copyable:

  • A tree-structure implementation where your data is placed in a contiguous region of memory, but with nodes storing absolute addresses to child nodes
  • Creating multiple instances of some data for sake of multithreading performance (in order to reduce cache crashes), with owning pointers inside, pointing anywhere
  • You have a flat object without pointers, but with an embedded third party structure inside. The third party structure at some point in the future includes a pointer that should not exist twice or more.

So whenever memcopying, keep in mind to check whether pointers could be copied in that specific case, and if that would be okay.

Realise that is_trivially_copyable is only the "Syntax Check", not the "Semantic Test", in compiler parlance.

like image 27
Sebastian Mach Avatar answered Nov 11 '22 19:11

Sebastian Mach