Byte-byte copies of types in C ++ 11?

The C ++ 11 standard ensures that byte copies for bytes are always valid for POD types. But what about some trivial types?

Here is an example:

struct trivial { int x; int y; trivial(int i) : x(2 * i) { std::cout << "Constructed." << std::endl; } }; 

If I had to copy this structure, byte per byte, is it guaranteed to be the correct copy, although this is not technically a POD? When is a line indicated, when cannot byte copy an object be done?

+5
source share
3 answers

Yes, it will be copied correctly.

Quoting FDIS, §3.9 / 2:

For any object (except a subobject of the base class) of a trivially copied type T , whether the object has a valid value of type T , the underlying bytes of the object can be copied to an array from char or unsigned char . If the contents of a char or unsigned char array are copied back to the object, the object subsequently retains its original value.

And §3.9 / 3:

For any trivially copied type T , if two pointers to T point to different objects T obj1 and obj2 , where neither obj1 nor obj2 is a subobject of the base class, if the base bytes that make up obj1 are copied to obj2 , obj2 will subsequently have the same value as obj1 .

So, the requirements you are asking for are §3.9 / 9:

Arithmetic types, enumeration types, pointer types, a pointer to member types, std::nullptr_t and cv-qualification versions of these types are collectively called scalar types. Scalar types, POD classes, arrays of such types, and cv-qualified versions of these types are collectively called POD types. Scalar types, types of types, types with the ability to copy, arrays of such types, and cv-qualification versions of these types are collectively called trivially copied types .

And §9 / 6:

A trivially-copied class is a class that:

  • no nontrivial copy constructors,
  • no nontrivial move constructors,
  • no nontrivial copy assignment operators,
  • has no nontrivial move assignment operators and
  • has a trivial destructor.
+9
source

C ++ 11 broke the definition of POD types into more useful categories, in particular the "trivial" and the "standard layout". Your example is the standard layout and trivially copied, although the constructor does not allow it to be completely trivial. It is guaranteed that trivially copied types will be safely copied by bytes:

For any object (except the subobject of the base class), the copy type T is trivial, regardless of whether the object has a valid value of type T, the base bytes (1.7) that make up the object can be copied to the char array or unsigned char.40 If the contents of the char array or unsigned char is copied back to the object, the object must subsequently retain its original value.

So no, POD status is not required for safe copying in this way, but you can identify a subset of the non-POD types that may be.

+5
source

If the standard state is defined only for POD types (I have not studied the C ++ 11 standard yet, but I don’t know if your statement is correct or not (a) ), and you do it for a non-POD type, this is not defined behavior . Period.

It can work on some implementations in some environments at certain times of the day when the planets are aligned. It can work the vast majority of times. This still does not make a good idea if you value portability.


(a) After a more thorough investigation, your specific case seems to be in order. Section 3.9 / 3 of the standard ( n3242 draft , but I would be surprised if it changed a lot from this late draft):

For any trivially copied type T, if two pointers to T point to different T-objects obj1 and obj2, where neither obj1 nor obj2 are a subobject of the base class, if the base bytes that make up obj1 are copied to obj2, obj2 then save then same value as obj1.

Section 9 defines (at a high level) what “trivially copied” means:

A trivially copied class is a class that: - does not have non-trivial copy constructors (12.8),
- there are no non-trivial displacement constructors (12.8),
- does not have non-trivial copy assignment operators (13.5.3, 12.8),
- there are no nontrivial displacement assignment operators (13.5.3, 12.8) and
- has a trivial destructor (12.4).

when these sections will be discussed in more detail in each area, 12.8 for copying and moving class objects and 13.5.3 for assignments.

+3
source

All Articles