The C++11 standard guarantees that byte-for-byte copies are always valid for POD types. But what about certain trivial types?
Here's an example:
struct trivial
{
int x;
int y;
trivial(int i) : x(2 * i) { std::cout << "Constructed." << std::endl; }
};
If I were to copy this struct, byte-for-byte, is it guaranteed to copy properly, even though it isn't technically a POD? When is the line drawn as to when it's not okay to byte-copy an object?
Yes, it is guaranteed to copy properly.
Quoting the FDIS, §3.9/2:
For any object (other than a base-class subobject) of trivially copyable type
T
, whether or not the object holds a valid value of typeT
, the underlying bytes making up the object can be copied into an array ofchar
orunsigned char
. If the content of the array ofchar
orunsigned char
is copied back into the object, the object shall subsequently hold its original value.
And §3.9/3:
For any trivially copyable type
T
, if two pointers toT
point to distinctT
objectsobj1
andobj2
, where neitherobj1
norobj2
is a base-class subobject, if the underlying bytes making upobj1
are copied intoobj2
,obj2
shall subsequently hold the same value asobj1
.
So the requirements you're asking about are, §3.9/9:
Arithmetic types, enumeration types, pointer types, pointer to member types,
std::nullptr_t
, and cv-qualified 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, trivially copyable class types, arrays of such types, and cv-qualified versions of these types are collectively called trivially copyable types.
And §9/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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With