This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

360
cppdraft/intro/object.md Normal file
View File

@@ -0,0 +1,360 @@
[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.2Object model[intro.object]") is created
by a [definition](basic.def "6.2Declarations and definitions[basic.def]"),
by a [*new-expression*](expr.new#nt:new-expression "7.6.2.8New[expr.new]") ([[expr.new]](expr.new "7.6.2.8New")),
by an operation that implicitly creates objects (see below),
when implicitly changing the active member of a [union](class.union "11.5Unions[class.union]"),
or
when a temporary object is created ([[conv.rval]](conv.rval "7.3.5Temporary materialization conversion"), [[class.temporary]](class.temporary "6.8.7Temporary objects"))[.](#1.sentence-2)
An object occupies a region of storage
in its period of construction ([[class.cdtor]](class.cdtor "11.9.5Construction and destruction")),
throughout its [lifetime](basic.life "6.8.4Lifetime[basic.life]"),
and
in its period of destruction ([[class.cdtor]](class.cdtor "11.9.5Construction 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.1Preamble"))[.](#1.sentence-6)
An object has a storage
duration ([[basic.stc]](basic.stc "6.8.6Storage duration")) which influences its
lifetime ([[basic.life]](basic.life "6.8.4Lifetime"))[.](#1.sentence-7)
An object has a
type ([[basic.types]](basic.types "6.9Types"))[.](#1.sentence-8)
[*Note [2](#note-2)*:
Some objects are
polymorphic ([[class.virtual]](class.virtual "11.7.3Virtual 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.2Object model[intro.object]")[.](#2.sentence-1)
A subobject can be
a [*member subobject*](#def:member_subobject "6.8.2Object model[intro.object]") ([[class.mem]](class.mem "11.4Class members")), a [*base class subobject*](#def:base_class_subobject "6.8.2Object model[intro.object]") ([[class.derived]](class.derived "11.7Derived 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.2Object 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.8New"))
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.1Header <cstddef> synopsis")),
that array [*provides storage*](#def:provides_storage "6.8.2Object 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.4Lifetime"))[.](#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.2Object 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.2Object 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.2Object 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.2Object 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.2Object 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.11No 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.10Bit-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.1General")) 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.2Object model[intro.object]") if it is
- [(9.1)](#9.1)
a string literal object ([[lex.string]](lex.string "5.13.5String literals")),
- [(9.2)](#9.2)
the backing array of an initializer list ([[dcl.init.ref]](dcl.init.ref "9.5.4References")), 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.15Promoting 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.6Qualification 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.2Object 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.1General"))
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.2Object 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.4Compound 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.6Explicit lifetime management"), [[c.malloc]](c.malloc "20.2.12C library memory allocation"), [[mem.res.public]](mem.res.public "20.5.2.2Public member functions"), [[bit.cast]](bit.cast "22.11.3Function template bit_­cast"), [[cstring.syn]](cstring.syn "27.5.1Header <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.1Sequential execution"))[.](#footnote-20.sentence-1)