[basic.types.general]

# 6 Basics [[basic]](./#basic)

## 6.9 Types [[basic.types]](basic.types#general)

### 6.9.1 General [basic.types.general]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5030)

[*Note [1](#note-1)*:

[[basic.types]](basic.types "6.9 Types") and the subclauses thereof
impose requirements on implementations regarding the representation
of types[.](#1.sentence-1)

There are two kinds of types: fundamental types and compound types[.](#1.sentence-2)

Types describe [objects](intro.object "6.8.2 Object model [intro.object]"),[references](dcl.ref "9.3.4.3 References [dcl.ref]"),
or [functions](dcl.fct "9.3.4.6 Functions [dcl.fct]")[.](#1.sentence-3)

â *end note*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5041)

For any object (other than a potentially-overlapping subobject) of trivially copyable typeT, whether or not the object holds a valid value of typeT, the underlying bytes ([[intro.memory]](intro.memory "6.8.1 Memory model")) making up the
object can be copied into an array ofchar,unsigned char, orstd​::​byte ([[cstddef.syn]](cstddef.syn "17.2.1 Header <cstddef> synopsis"))[.](#2.sentence-1)[26](#footnote-26 "By using, for example, the library functions ([headers]) std​::​memcpy or std​::​memmove.")

If the content of that array
is copied back into the object, the object shall
subsequently hold its original value[.](#2.sentence-2)

[*Example [1](#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*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5068)

For two distinct objects obj1 and obj2 of trivially copyable type T,
where neither obj1 nor obj2 is a potentially-overlapping subobject,
if the underlying bytes ([[intro.memory]](intro.memory "6.8.1 Memory model")) making upobj1 are copied into obj2,[27](#footnote-27 "By using, for example, the library functions ([headers]) std​::​memcpy or std​::​memmove.")obj2 shall subsequently hold the same value asobj1[.](#3.sentence-1)

[*Example [2](#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*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5092)

The [*object representation*](#def:representation,object "6.9.1 General [basic.types.general]") of a complete object type T is the
sequence of *N* unsigned char objects taken up
by a non-bit-field complete object of type T,
where *N* equalssizeof(T)[.](#4.sentence-1)

The [*value representation*](#def:representation,value "6.9.1 General [basic.types.general]") of a type T is the set of bits
in the object representation of T that participate in representing a value of type T[.](#4.sentence-2)

The object and value representation of
a non-bit-field complete object of type T are
the bytes and bits, respectively, of
the object corresponding to the object and value representation of its type[.](#4.sentence-3)

The object representation of a bit-field object is
the sequence of *N* bits taken up by the object,
where *N* is the width of the bit-field ([[class.bit]](class.bit "11.4.10 Bit-fields"))[.](#4.sentence-4)

The value representation of a bit-field object is
the set of bits in the object representation that
participate in representing its value[.](#4.sentence-5)

Bits in the object representation of a type or object that are
not part of the value representation
are [*padding bits*](#def:padding_bits "6.9.1 General [basic.types.general]")[.](#4.sentence-6)

For trivially copyable types, the value representation is
a set of bits in the object representation that determines a[*value*](#def:value "6.9.1 General [basic.types.general]"), which is one discrete element of animplementation-defined set of values[.](#4.sentence-7)[28](#footnote-28 "The intent is that the memory model of C++ is compatible with that of the C programming language.")

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5127)

A class that has been declared but not defined, an enumeration type in certain
contexts ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")), or an array of unknown
bound or of incomplete element type, is an[*incompletely-defined object type*](#def:object_type,incompletely-defined "6.9.1 General [basic.types.general]")[.](#5.sentence-1)[29](#footnote-29 "The size and layout of an instance of an incompletely-defined object type is unknown.")

Incompletely-defined object types and cv void are[*incomplete types*](#def:type,incomplete "6.9.1 General [basic.types.general]") ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#5.sentence-2)

[*Note [2](#note-2)*:

Objects cannot be defined to have an incomplete type ([[basic.def]](basic.def "6.2 Declarations and definitions"))[.](#5.sentence-3)

â *end note*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5144)

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[.](#6.sentence-1)

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[.](#6.sentence-2)

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 ofN Tâ) are different types[.](#6.sentence-3)

[*Note [3](#note-3)*:

The type of a pointer or reference to array of unknown bound
permanently points to or refers to an incomplete type[.](#6.sentence-4)

An array of unknown bound named by a typedef declaration
permanently refers to an incomplete type[.](#6.sentence-5)

In either case, the array type cannot be completed[.](#6.sentence-6)

â *end note*]

[*Example [3](#example-3)*:

[ð](#:type,example_of_incomplete)

class X; // X is an incomplete typeextern X* xp; // xp is a pointer to an incomplete typeextern int arr[]; // the type of arr is incompletetypedef int 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; // OK; qualification conversion ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")) xp++; // OK, X is complete arrp++; // error: UNKA can't be completed} â *end example*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5192)

[*Note [4](#note-4)*:

The rules for declarations and expressions describe in which
contexts incomplete types are prohibited[.](#7.sentence-1)

â *end note*]

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5198)

An [*object type*](#def:object_type "6.9.1 General [basic.types.general]") is a (possibly cv-qualified) type that is not
a function type, not a reference type, and not cv void[.](#8.sentence-1)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5203)

Arithmetic types ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")), enumeration types,
pointer types, pointer-to-member types ([[basic.compound]](basic.compound "6.9.4 Compound types")),std​::​meta​::​​info, std​::​nullptr_t,
and[cv-qualified](basic.type.qualifier "6.9.5 CV-qualifiers [basic.type.qualifier]") versions of these
types are collectively called[*scalar types*](#def:type,scalar "6.9.1 General [basic.types.general]")[.](#9.sentence-1)

Scalar types, trivially copyable class types ([[class.prop]](class.prop "11.2 Properties of classes")),
arrays of such types, and cv-qualified versions of these
types are collectively called [*trivially copyable types*](#def:type,trivially_copyable "6.9.1 General [basic.types.general]")[.](#9.sentence-2)

Scalar types, trivially relocatable class types ([[class.prop]](class.prop "11.2 Properties of classes")),
arrays of such types, and cv-qualified versions of these
types are collectively called [*trivially relocatable types*](#def:type,trivially_relocatable "6.9.1 General [basic.types.general]")[.](#9.sentence-3)

Cv-unqualified scalar types, replaceable class types ([[class.prop]](class.prop "11.2 Properties of classes")), and
arrays of such types are collectively called[*replaceable types*](#def:type,replaceable "6.9.1 General [basic.types.general]")[.](#9.sentence-4)

Scalar types, standard-layout class
types ([[class.prop]](class.prop "11.2 Properties of classes")), arrays of such types, and
cv-qualified versions of these types
are collectively called [*standard-layout types*](#def:type,standard-layout "6.9.1 General [basic.types.general]")[.](#9.sentence-5)

Scalar types, implicit-lifetime class types ([[class.prop]](class.prop "11.2 Properties of classes")),
array types, and cv-qualified versions of these types
are collectively called [*implicit-lifetime types*](#def:type,implicit-lifetime "6.9.1 General [basic.types.general]")[.](#9.sentence-6)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5238)

A type is a [*literal type*](#def:type,literal "6.9.1 General [basic.types.general]") if it is:

- [(10.1)](#10.1)

cv void; or

- [(10.2)](#10.2)

a scalar type; or

- [(10.3)](#10.3)

a reference type; or

- [(10.4)](#10.4)

an array of literal type; or

- [(10.5)](#10.5)

a possibly cv-qualified [class type](class "11 Classes [class]") that
has all of the following properties:
  * [(10.5.1)](#10.5.1)

it has a constexpr destructor ([[dcl.constexpr]](dcl.constexpr "9.2.6 The constexpr and consteval specifiers")),

  * [(10.5.2)](#10.5.2)

all of its non-variant non-static data members and base classes are of non-volatile literal types, and

  * [(10.5.3)](#10.5.3)

it
    +
          [(10.5.3.1)](#10.5.3.1)
is a closure type ([[expr.prim.lambda.closure]](expr.prim.lambda.closure "7.5.6.2 Closure types")),

    +
          [(10.5.3.2)](#10.5.3.2)
is an aggregate union type that has either
no variant members or
at least one variant member of non-volatile literal type,

    +
          [(10.5.3.3)](#10.5.3.3)
is a non-union aggregate type for which
each of its anonymous union members
satisfies the above requirements for an aggregate union type, or

    +
          [(10.5.3.4)](#10.5.3.4)
has at least one constexpr constructor or constructor template
(possibly inherited ([[namespace.udecl]](namespace.udecl "9.10 The using declaration")) from a base class)
that is not a copy or move constructor[.](#10.sentence-1)

[*Note [5](#note-5)*:

A literal type is one for which
it might be possible to create an object
within a constant expression[.](#10.sentence-2)

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[.](#10.sentence-3)

â *end note*]

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5275)

Two types *cv1* T1 and *cv2* T2 are[*layout-compatible types*](#def:type,layout-compatible "6.9.1 General [basic.types.general]") if T1 and T2 are the same type,[layout-compatible enumerations](dcl.enum#def:layout-compatible,enumeration "9.8.1 Enumeration declarations [dcl.enum]"), or[layout-compatible standard-layout class types](class.mem#def:layout-compatible,class "11.4 Class members [class.mem]")[.](#11.sentence-1)

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/basic.tex#L5283)

A type is [*consteval-only*](#def:consteval-only "6.9.1 General [basic.types.general]") if it is eitherstd​::​meta​::​info or
a type compounded from a consteval-only type ([[basic.compound]](basic.compound "6.9.4 Compound types"))[.](#12.sentence-1)

Every object of consteval-only type shall be

- [(12.1)](#12.1)

the object associated with a constexpr variable or a subobject thereof,

- [(12.2)](#12.2)

a template parameter object ([[temp.param]](temp.param "13.2 Template parameters")) or a subobject thereof, or

- [(12.3)](#12.3)

an object whose lifetime begins and ends
during the evaluation of a core constant expression[.](#12.sentence-2)

[26)](#footnote-26)[26)](#footnoteref-26)

By using, for example, the library
functions ([[headers]](headers "16.4.2.3 Headers")) std​::​memcpy or std​::​memmove[.](#footnote-26.sentence-1)

[27)](#footnote-27)[27)](#footnoteref-27)

By using, for example,
the library functions ([[headers]](headers "16.4.2.3 Headers")) std​::​memcpy or std​::​memmove[.](#footnote-27.sentence-1)

[28)](#footnote-28)[28)](#footnoteref-28)

The intent is that the memory model of C++ is compatible
with that of the C programming language[.](#footnote-28.sentence-1)

[29)](#footnote-29)[29)](#footnoteref-29)

The size and layout of an instance of an incompletely-defined
object type is unknown[.](#footnote-29.sentence-1)
