- tmp/tmpsr8xwv2b/{from.md → to.md} +106 -20
tmp/tmpsr8xwv2b/{from.md → to.md}
RENAMED
|
@@ -1,59 +1,145 @@
|
|
| 1 |
## The C++object model <a id="intro.object">[[intro.object]]</a>
|
| 2 |
|
| 3 |
The constructs in a C++program create, destroy, refer to, access, and
|
| 4 |
-
manipulate objects. An *object* is
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
[[
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
information associated with each such object that makes it possible to
|
| 16 |
determine that object’s type during program execution. For other
|
| 17 |
objects, the interpretation of the values found therein is determined by
|
| 18 |
the type of the *expression*s (Clause [[expr]]) used to access them.
|
| 19 |
|
| 20 |
Objects can contain other objects, called *subobjects*. A subobject can
|
| 21 |
be a *member subobject* ([[class.mem]]), a *base class subobject*
|
| 22 |
(Clause [[class.derived]]), or an array element. An object that is not
|
| 23 |
-
a subobject of any other object is called a *complete object*.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
For every object `x`, there is some object called the *complete object
|
| 26 |
of* `x`, determined as follows:
|
| 27 |
|
| 28 |
-
- If `x` is a complete object, then
|
|
|
|
| 29 |
- Otherwise, the complete object of `x` is the complete object of the
|
| 30 |
(unique) object that contains `x`.
|
| 31 |
|
| 32 |
If a complete object, a data member ([[class.mem]]), or an array
|
| 33 |
element is of class type, its type is considered the *most derived
|
| 34 |
class*, to distinguish it from the class type of any base class
|
| 35 |
subobject; an object of a most derived class type or of a non-class type
|
| 36 |
is called a *most derived object*.
|
| 37 |
|
| 38 |
Unless it is a bit-field ([[class.bit]]), a most derived object shall
|
| 39 |
-
have a
|
| 40 |
class subobjects may have zero size. An object of trivially copyable or
|
| 41 |
standard-layout type ([[basic.types]]) shall occupy contiguous bytes of
|
| 42 |
storage.
|
| 43 |
|
| 44 |
Unless an object is a bit-field or a base class subobject of zero size,
|
| 45 |
the address of that object is the address of the first byte it occupies.
|
| 46 |
-
Two objects
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
distinct addresses.[^
|
|
|
|
|
|
|
| 50 |
|
| 51 |
``` cpp
|
| 52 |
static const char test1 = 'x';
|
| 53 |
static const char test2 = 'x';
|
| 54 |
const bool b = &test1 != &test2; // always true
|
| 55 |
```
|
| 56 |
|
| 57 |
-
|
| 58 |
-
|
|
|
|
|
|
|
|
|
|
| 59 |
|
|
|
|
| 1 |
## The C++object model <a id="intro.object">[[intro.object]]</a>
|
| 2 |
|
| 3 |
The constructs in a C++program create, destroy, refer to, access, and
|
| 4 |
+
manipulate objects. An *object* is created by a definition (
|
| 5 |
+
[[basic.def]]), by a *new-expression* ([[expr.new]]), when implicitly
|
| 6 |
+
changing the active member of a union ([[class.union]]), or when a
|
| 7 |
+
temporary object is created ([[conv.rval]], [[class.temporary]]). An
|
| 8 |
+
object occupies a region of storage in its period of construction (
|
| 9 |
+
[[class.cdtor]]), throughout its lifetime ([[basic.life]]), and in its
|
| 10 |
+
period of destruction ([[class.cdtor]]).
|
| 11 |
+
|
| 12 |
+
[*Note 1*: A function is not an object, regardless of whether or not it
|
| 13 |
+
occupies storage in the way that objects do. — *end note*]
|
| 14 |
+
|
| 15 |
+
The properties of an object are determined when the object is created.
|
| 16 |
+
An object can have a name (Clause [[basic]]). An object has a storage
|
| 17 |
+
duration ([[basic.stc]]) which influences its lifetime (
|
| 18 |
+
[[basic.life]]). An object has a type ([[basic.types]]). Some objects
|
| 19 |
+
are polymorphic ([[class.virtual]]); the implementation generates
|
| 20 |
information associated with each such object that makes it possible to
|
| 21 |
determine that object’s type during program execution. For other
|
| 22 |
objects, the interpretation of the values found therein is determined by
|
| 23 |
the type of the *expression*s (Clause [[expr]]) used to access them.
|
| 24 |
|
| 25 |
Objects can contain other objects, called *subobjects*. A subobject can
|
| 26 |
be a *member subobject* ([[class.mem]]), a *base class subobject*
|
| 27 |
(Clause [[class.derived]]), or an array element. An object that is not
|
| 28 |
+
a subobject of any other object is called a *complete object*. If an
|
| 29 |
+
object is created in storage associated with a member subobject or array
|
| 30 |
+
element *e* (which may or may not be within its lifetime), the created
|
| 31 |
+
object is a subobject of *e*’s containing object if:
|
| 32 |
+
|
| 33 |
+
- the lifetime of *e*’s containing object has begun and not ended, and
|
| 34 |
+
- the storage for the new object exactly overlays the storage location
|
| 35 |
+
associated with *e*, and
|
| 36 |
+
- the new object is of the same type as *e* (ignoring cv-qualification).
|
| 37 |
+
|
| 38 |
+
[*Note 2*: If the subobject contains a reference member or a `const`
|
| 39 |
+
subobject, the name of the original subobject cannot be used to access
|
| 40 |
+
the new object ([[basic.life]]). — *end note*]
|
| 41 |
+
|
| 42 |
+
[*Example 1*:
|
| 43 |
+
|
| 44 |
+
``` cpp
|
| 45 |
+
struct X { const int n; };
|
| 46 |
+
union U { X x; float f; };
|
| 47 |
+
void tong() {
|
| 48 |
+
U u = {{ 1 }};
|
| 49 |
+
u.f = 5.f; // OK, creates new subobject of u ([class.union])
|
| 50 |
+
X *p = new (&u.x) X {2}; // OK, creates new subobject of u
|
| 51 |
+
assert(p->n == 2); // OK
|
| 52 |
+
assert(*std::launder(&u.x.n) == 2); // OK
|
| 53 |
+
assert(u.x.n == 2); // undefined behavior, u.x does not name new subobject
|
| 54 |
+
}
|
| 55 |
+
```
|
| 56 |
+
|
| 57 |
+
— *end example*]
|
| 58 |
+
|
| 59 |
+
If a complete object is created ([[expr.new]]) in storage associated
|
| 60 |
+
with another object *e* of type “array of N `unsigned char`” or of type
|
| 61 |
+
“array of N `std::byte`” ([[cstddef.syn]]), that array *provides
|
| 62 |
+
storage* for the created object if:
|
| 63 |
+
|
| 64 |
+
- the lifetime of *e* has begun and not ended, and
|
| 65 |
+
- the storage for the new object fits entirely within *e*, and
|
| 66 |
+
- there is no smaller array object that satisfies these constraints.
|
| 67 |
+
|
| 68 |
+
[*Note 3*: If that portion of the array previously provided storage for
|
| 69 |
+
another object, the lifetime of that object ends because its storage was
|
| 70 |
+
reused ([[basic.life]]). — *end note*]
|
| 71 |
+
|
| 72 |
+
[*Example 2*:
|
| 73 |
+
|
| 74 |
+
``` cpp
|
| 75 |
+
template<typename ...T>
|
| 76 |
+
struct AlignedUnion {
|
| 77 |
+
alignas(T...) unsigned char data[max(sizeof(T)...)];
|
| 78 |
+
};
|
| 79 |
+
int f() {
|
| 80 |
+
AlignedUnion<int, char> au;
|
| 81 |
+
int *p = new (au.data) int; // OK, au.data provides storage
|
| 82 |
+
char *c = new (au.data) char(); // OK, ends lifetime of *p
|
| 83 |
+
char *d = new (au.data + 1) char();
|
| 84 |
+
return *c + *d; // OK
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
struct A { unsigned char a[32]; };
|
| 88 |
+
struct B { unsigned char b[16]; };
|
| 89 |
+
A a;
|
| 90 |
+
B *b = new (a.a + 8) B; // a.a provides storage for *b
|
| 91 |
+
int *p = new (b->b + 4) int; // b->b provides storage for *p
|
| 92 |
+
// a.a does not provide storage for *p (directly),
|
| 93 |
+
// but *p is nested within a (see below)
|
| 94 |
+
```
|
| 95 |
+
|
| 96 |
+
— *end example*]
|
| 97 |
+
|
| 98 |
+
An object *a* is *nested within* another object *b* if:
|
| 99 |
+
|
| 100 |
+
- *a* is a subobject of *b*, or
|
| 101 |
+
- *b* provides storage for *a*, or
|
| 102 |
+
- there exists an object *c* where *a* is nested within *c*, and *c* is
|
| 103 |
+
nested within *b*.
|
| 104 |
|
| 105 |
For every object `x`, there is some object called the *complete object
|
| 106 |
of* `x`, determined as follows:
|
| 107 |
|
| 108 |
+
- If `x` is a complete object, then the complete object of `x` is
|
| 109 |
+
itself.
|
| 110 |
- Otherwise, the complete object of `x` is the complete object of the
|
| 111 |
(unique) object that contains `x`.
|
| 112 |
|
| 113 |
If a complete object, a data member ([[class.mem]]), or an array
|
| 114 |
element is of class type, its type is considered the *most derived
|
| 115 |
class*, to distinguish it from the class type of any base class
|
| 116 |
subobject; an object of a most derived class type or of a non-class type
|
| 117 |
is called a *most derived object*.
|
| 118 |
|
| 119 |
Unless it is a bit-field ([[class.bit]]), a most derived object shall
|
| 120 |
+
have a nonzero size and shall occupy one or more bytes of storage. Base
|
| 121 |
class subobjects may have zero size. An object of trivially copyable or
|
| 122 |
standard-layout type ([[basic.types]]) shall occupy contiguous bytes of
|
| 123 |
storage.
|
| 124 |
|
| 125 |
Unless an object is a bit-field or a base class subobject of zero size,
|
| 126 |
the address of that object is the address of the first byte it occupies.
|
| 127 |
+
Two objects *a* and *b* with overlapping lifetimes that are not
|
| 128 |
+
bit-fields may have the same address if one is nested within the other,
|
| 129 |
+
or if at least one is a base class subobject of zero size and they are
|
| 130 |
+
of different types; otherwise, they have distinct addresses.[^5]
|
| 131 |
+
|
| 132 |
+
[*Example 3*:
|
| 133 |
|
| 134 |
``` cpp
|
| 135 |
static const char test1 = 'x';
|
| 136 |
static const char test2 = 'x';
|
| 137 |
const bool b = &test1 != &test2; // always true
|
| 138 |
```
|
| 139 |
|
| 140 |
+
— *end example*]
|
| 141 |
+
|
| 142 |
+
[*Note 4*: C++provides a variety of fundamental types and several ways
|
| 143 |
+
of composing new types from existing types (
|
| 144 |
+
[[basic.types]]). — *end note*]
|
| 145 |
|