For any object (other than a potentially-overlapping subobject) of trivially copyable type
T, whether or not the object holds a valid value of type
T, the underlying bytes ([intro.memory]) making up the
object can be copied into an array of
char,
unsignedchar, or
std::byte ([cstddef.syn]).40
If the content of that array
is copied back into the object, the object shall
subsequently hold its original value.
[Example 1: constexpr std::size_t N =sizeof(T);
char buf[N];
T obj; // obj initialized to its original value
std::memcpy(buf, &obj, N); // between these two calls to std::memcpy, obj might be modified
std::memcpy(&obj, buf, N); // at this point, each subobject of obj of scalar type holds its original value — end example]
For any trivially copyable type T, if two pointers to T point to
distinct T objects obj1 and obj2, where neither
obj1 nor obj2 is a potentially-overlapping subobject, if the underlying
bytes ([intro.memory]) making up
obj1 are copied into obj2,41obj2 shall subsequently hold the same value as
obj1.
[Example 2: T* t1p;
T* t2p;
// provided that t2p points to an initialized object ...
std::memcpy(t1p, t2p, sizeof(T));
// at this point, every subobject of trivially copyable type in *t1p contains// the same value as the corresponding subobject in *t2p — end example]
The object representation
of an object of type T is the
sequence of Nunsignedchar objects taken up
by the object of type T, where N equals
sizeof(T).
The value representation
of an object of type T is the set of bits
that participate in representing a value of type T.
Bits in the object representation that are not part of the value representation
are padding bits.
For trivially copyable types, the value representation is
a set of bits in the object representation that determines a
value, which is one discrete element of an
implementation-defined set of values.42
A class that has been declared but not defined, an enumeration type in certain
contexts ([dcl.enum]), or an array of unknown
bound or of incomplete element type, is an
incompletely-defined object type.43
A class type (such as “class X”) can be incomplete at one
point in a translation unit and complete later on; the type
“class X” is the same type at both points.
The declared type
of an array object can be an array of incomplete class type and
therefore incomplete; if the class type is completed later on in the
translation unit, the array type becomes complete; the array type at
those two points is the same type.
The declared type of an array object
can be an array of unknown bound and therefore be incomplete at one
point in a translation unit and complete later on; the array types at
those two points (“array of unknown bound of T” and “array of
NT”) are different types.
The type of a pointer to array of
unknown bound, or of a type defined by a typedef declaration to
be an array of unknown bound, cannot be completed.
[Example 3: class X; // X is an incomplete typeextern X* xp; // xp is a pointer to an incomplete typeexternint arr[]; // the type of arr is incompletetypedefint UNKA[]; // UNKA is an incomplete type
UNKA* arrp; // arrp is a pointer to an incomplete type
UNKA** arrpp;
void foo(){
xp++; // error: X is incomplete
arrp++; // error: incomplete type
arrpp++; // OK: sizeof UNKA* is known}struct X {int i; }; // now X is a complete typeint arr[10]; // now the type of arr is complete
X x;
void bar(){
xp =&x; // OK; type is “pointer to X”
arrp =&arr; // error: different types
xp++; // OK: X is complete
arrp++; // error: UNKA can't be completed} — end example]
Scalar types, trivially copyable class types ([class.prop]),
arrays of such types, and cv-qualified versions of these
types are collectively called trivially copyable types.
Scalar types, trivial class types ([class.prop]),
arrays of such types and cv-qualified versions of these
types are collectively called
trivial types.
Scalar types, standard-layout class
types ([class.prop]), arrays of such types and
cv-qualified versions of these types
are collectively called standard-layout types.
Scalar types, implicit-lifetime class types ([class.prop]),
array types, and cv-qualified versions of these types
are collectively called implicit-lifetime types.
it is either a closure type ([expr.prim.lambda.closure]),
an aggregate type ([dcl.init.aggr]), or
has at least one constexpr constructor or constructor template
(possibly inherited from a base class)
that is not a copy or move constructor,
A literal type is one for which
it might be possible to create an object
within a constant expression.
It is not a guarantee that it is possible to create such an object,
nor is it a guarantee that any object of that type
will be usable in a constant expression.