[intro.object]

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

## 6.8 Memory and objects [[basic.memobj]](basic.memobj#intro.object)

### 6.8.2 Object model [intro.object]

[1](#1)

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

The constructs in a C++ program create, destroy, refer to, access, and
manipulate objects[.](#1.sentence-1)

An [*object*](#def:object "6.8.2 Object model [intro.object]") is created
by a [definition](basic.def "6.2 Declarations and definitions [basic.def]"),
by a [*new-expression*](expr.new#nt:new-expression "7.6.2.8 New [expr.new]") ([[expr.new]](expr.new "7.6.2.8 New")),
by an operation that implicitly creates objects (see below),
when implicitly changing the active member of a [union](class.union "11.5 Unions [class.union]"),
or
when a temporary object is created ([[conv.rval]](conv.rval "7.3.5 Temporary materialization conversion"), [[class.temporary]](class.temporary "6.8.7 Temporary objects"))[.](#1.sentence-2)

An object occupies a region of storage
in its period of construction ([[class.cdtor]](class.cdtor "11.9.5 Construction and destruction")),
throughout its [lifetime](basic.life "6.8.4 Lifetime [basic.life]"),
and
in its period of destruction ([[class.cdtor]](class.cdtor "11.9.5 Construction and destruction"))[.](#1.sentence-3)

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

A function is not an object, regardless of whether or not it
occupies storage in the way that objects do[.](#1.sentence-4)

â *end note*]

The properties of an
object are determined when the object is created[.](#1.sentence-5)

An object can have a
name ([[basic.pre]](basic.pre "6.1 Preamble"))[.](#1.sentence-6)

An object has a storage
duration ([[basic.stc]](basic.stc "6.8.6 Storage duration")) which influences its
lifetime ([[basic.life]](basic.life "6.8.4 Lifetime"))[.](#1.sentence-7)

An object has a
type ([[basic.types]](basic.types "6.9 Types"))[.](#1.sentence-8)

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

Some objects are
polymorphic ([[class.virtual]](class.virtual "11.7.3 Virtual functions")); the implementation
generates information associated with each such object that makes it
possible to determine that object's type during program execution[.](#1.sentence-9)

â *end note*]

[2](#2)

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

Objects can contain other objects, called [*subobjects*](#def:subobject "6.8.2 Object model [intro.object]")[.](#2.sentence-1)

A subobject can be
a [*member subobject*](#def:member_subobject "6.8.2 Object model [intro.object]") ([[class.mem]](class.mem "11.4 Class members")), a [*base class subobject*](#def:base_class_subobject "6.8.2 Object model [intro.object]") ([[class.derived]](class.derived "11.7 Derived classes")),
or an array element[.](#2.sentence-2)

An object that is not a subobject of any other object is called a [*complete
object*](#def:complete_object "6.8.2 Object model [intro.object]")[.](#2.sentence-3)

If an object is created
in storage associated with a member subobject or array element *e* (which may or may not be within its lifetime),
the created object
is a subobject of *e*'s containing object if

- [(2.1)](#2.1)

the lifetime of *e*'s containing object has begun and not ended, and

- [(2.2)](#2.2)

the storage for the new object exactly overlays the storage location associated with *e*, and

- [(2.3)](#2.3)

the new object is of the same type as *e* (ignoring cv-qualification)[.](#2.sentence-4)

[3](#3)

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

If a complete object is created ([[expr.new]](expr.new "7.6.2.8 New"))
in storage associated with another object *e* of type âarray of N unsigned charâ or
of type âarray of N std​::​byteâ ([[cstddef.syn]](cstddef.syn "17.2.1 Header <cstddef> synopsis")),
that array [*provides storage*](#def:provides_storage "6.8.2 Object model [intro.object]") for the created object if

- [(3.1)](#3.1)

the lifetime of *e* has begun and not ended, and

- [(3.2)](#3.2)

the storage for the new object fits entirely within *e*, and

- [(3.3)](#3.3)

there is no array object that satisfies these constraints nested within *e*[.](#3.sentence-1)

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

If that portion of the array
previously provided storage for another object,
the lifetime of that object ends
because its storage was reused ([[basic.life]](basic.life "6.8.4 Lifetime"))[.](#3.sentence-2)

â *end note*]

[*Example [1](#example-1)*: // assumes that sizeof(int) is equal to 4template<typename ...T>struct AlignedUnion {alignas(T...) unsigned char data[max(sizeof(T)...)];};int f() { AlignedUnion<int, char> au; int *p = new (au.data) int; // OK, au.data provides storagechar *c = new (au.data) char(); // OK, ends lifetime of *pchar *d = new (au.data + 1) char(); return *c + *d; // OK}struct A { unsigned char a[32]; };struct B { unsigned char b[16]; };alignas(int) A a;
B *b = new (a.a + 8) B; // a.a provides storage for *bint *p = new (b->b + 4) int; // b->b provides storage for *p// a.a does not provide storage for *p (directly),// but *p is nested within a (see below) â *end example*]

[4](#4)

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

An object *a* is [*nested within*](#def:nested_within "6.8.2 Object model [intro.object]") another object *b* if

- [(4.1)](#4.1)

*a* is a subobject of *b*, or

- [(4.2)](#4.2)

*b* provides storage for *a*, or

- [(4.3)](#4.3)

there exists an object *c* where *a* is nested within *c*,
and *c* is nested within *b*[.](#4.sentence-1)

[5](#5)

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

For every object x, there is some object called the[*complete object of*](#def:complete_object_of "6.8.2 Object model [intro.object]") x, determined as follows:

- [(5.1)](#5.1)

  If x is a complete object, then the complete object
of x is itself[.](#5.1.sentence-1)

- [(5.2)](#5.2)

  Otherwise, the complete object of x is the complete object
of the (unique) object that contains x[.](#5.2.sentence-1)

[6](#6)

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

If a complete object, a member subobject, or an array element is of
class type, its type is considered the [*most derived
class*](#def:most_derived_class "6.8.2 Object model [intro.object]"), to distinguish it from the class type of any base class subobject;
an object of a most derived class type or of a non-class type is called a[*most derived object*](#def:most_derived_object "6.8.2 Object model [intro.object]")[.](#6.sentence-1)

[7](#7)

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

A [*potentially-overlapping subobject*](#def:potentially-overlapping_subobject "6.8.2 Object model [intro.object]") is either:

- [(7.1)](#7.1)

a base class subobject, or

- [(7.2)](#7.2)

a non-static data member
declared with the [no_unique_address](dcl.attr.nouniqueaddr "9.13.11 No unique address attribute [dcl.attr.nouniqueaddr]") attribute[.](#7.sentence-1)

[8](#8)

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

An object has nonzero size if it

- [(8.1)](#8.1)

is not a potentially-overlapping subobject, or

- [(8.2)](#8.2)

is not of class type, or

- [(8.3)](#8.3)

is of a class type with virtual member functions or virtual base classes, or

- [(8.4)](#8.4)

has subobjects of nonzero size or unnamed bit-fields of nonzero length[.](#8.sentence-1)

Otherwise, if the object is a base class subobject
of a standard-layout class type
with no non-static data members,
it has zero size[.](#8.sentence-2)

Otherwise, the circumstances under which the object has zero size
are implementation-defined[.](#8.sentence-3)

Unless it is a [bit-field](class.bit "11.4.10 Bit-fields [class.bit]"),
an object with nonzero size
shall occupy one or more bytes of storage,
including every byte that is occupied in full or in part
by any of its subobjects[.](#8.sentence-4)

An object of trivially copyable or
standard-layout type ([[basic.types.general]](basic.types.general "6.9.1 General")) shall occupy contiguous bytes of
storage[.](#8.sentence-5)

[9](#9)

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

An object is a [*potentially non-unique object*](#def:object,potentially_non-unique "6.8.2 Object model [intro.object]") if it is

- [(9.1)](#9.1)

a string literal object ([[lex.string]](lex.string "5.13.5 String literals")),

- [(9.2)](#9.2)

the backing array of an initializer list ([[dcl.init.ref]](dcl.init.ref "9.5.4 References")), or

- [(9.3)](#9.3)

the object introduced by a call to std​::​meta​::​reflect_constant_array or std​::​meta​::​​reflect_constant_string ([[meta.reflection.array]](meta.reflection.array "21.4.15 Promoting to static storage arrays")), or

- [(9.4)](#9.4)

a subobject thereof[.](#9.sentence-1)

[10](#10)

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

Unless an object is a bit-field or a subobject of zero size, the
address of that object is the address of the first byte it occupies[.](#10.sentence-1)

Two objects
with overlapping lifetimes
that are not bit-fields
may have the same address if

- [(10.1)](#10.1)

one is nested within the other,

- [(10.2)](#10.2)

at least one is a subobject of zero size and they are not of similar types ([[conv.qual]](conv.qual "7.3.6 Qualification conversions")),
or

- [(10.3)](#10.3)

they are both potentially non-unique objects;

otherwise, they have distinct addresses
and occupy disjoint bytes of storage[.](#10.sentence-2)[20](#footnote-20 "Under the âas-ifâ rule an implementation is allowed to store two objects at the same machine address or not store an object at all if the program cannot observe the difference ([intro.execution]).")

[*Example [2](#example-2)*: static const char test1 = 'x';static const char test2 = 'x';const bool b = &test1 != &test2; // always truestatic const char (&r) [] = "x";static const char *s = "x";static std::initializer_list<char> il = { 'x' };const bool b2 = r != il.begin(); // unspecified resultconst bool b3 = r != s; // unspecified resultconst bool b4 = il.begin() != &test1; // always trueconst bool b5 = r != &test1; // always true â *end example*]

The address of a non-bit-field subobject of zero size is
the address of an unspecified byte of storage
occupied by the complete object of that subobject[.](#10.sentence-3)

[11](#11)

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

Some operations are described as[*implicitly creating objects*](#def:object,implicit_creation "6.8.2 Object model [intro.object]") within a specified region of storage[.](#11.sentence-1)

For each operation that is specified as implicitly creating objects,
that operation implicitly creates and starts the lifetime of
zero or more objects of implicit-lifetime types ([[basic.types.general]](basic.types.general#term.implicit.lifetime.type "6.9.1 General"))
in its specified region of storage
if doing so would result in the program having defined behavior[.](#11.sentence-2)

If no such set of objects would give the program defined behavior,
the behavior of the program is undefined[.](#11.sentence-3)

If multiple such sets of objects would give the program defined behavior,
it is unspecified which such set of objects is created[.](#11.sentence-4)

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

Such operations do not start the lifetimes of subobjects of such objects
that are not themselves of implicit-lifetime types[.](#11.sentence-5)

â *end note*]

[12](#12)

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

Further, after implicitly creating objects within a specified region of storage,
some operations are described as producing a pointer to a[*suitable created object*](#def:object,suitable_created "6.8.2 Object model [intro.object]")[.](#12.sentence-1)

These operations select one of the implicitly-created objects
whose address is the address of the start of the region of storage,
and produce a pointer value that points to that object,
if that value would result in the program having defined behavior[.](#12.sentence-2)

If no such pointer value would give the program defined behavior,
the behavior of the program is undefined[.](#12.sentence-3)

If multiple such pointer values would give the program defined behavior,
it is unspecified which such pointer value is produced[.](#12.sentence-4)

[13](#13)

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

[*Example [3](#example-3)*: #include <cstdlib>struct X { int a, b; };
X *make_x() {// The call to std​::​malloc implicitly creates an object of type X// and its subobjects a and b, and returns a pointer to that X object// (or an object that is pointer-interconvertible ([[basic.compound]](basic.compound "6.9.4 Compound types")) with it),// in order to give the subsequent class member access operations// defined behavior. X *p = (X*)std::malloc(sizeof(struct X));
 p->a = 1;
 p->b = 2; return p;} â *end example*]

[14](#14)

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

Except during constant evaluation,
an operation that begins the lifetime of
an array of unsigned char or std​::​byte implicitly creates objects within the region of storage occupied by the array[.](#14.sentence-1)

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

The array object provides storage for these objects[.](#14.sentence-2)

â *end note*]

Except during constant evaluation,
any implicit or explicit invocation of a function
named operator new or operator new[] implicitly creates objects in the returned region of storage and
returns a pointer to a suitable created object[.](#14.sentence-3)

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

Some functions in the C++ standard library implicitly create
objects ([[obj.lifetime]](obj.lifetime "20.2.6 Explicit lifetime management"), [[c.malloc]](c.malloc "20.2.12 C library memory allocation"), [[mem.res.public]](mem.res.public "20.5.2.2 Public member functions"), [[bit.cast]](bit.cast "22.11.3 Function template bit_­cast"), [[cstring.syn]](cstring.syn "27.5.1 Header <cstring> synopsis"))[.](#14.sentence-4)

â *end note*]

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

Under the âas-ifâ rule an
implementation is allowed to store two objects at the same machine address or
not store an object at all if the program cannot observe the
difference ([[intro.execution]](intro.execution "6.10.1 Sequential execution"))[.](#footnote-20.sentence-1)
