From Jason Turner

[class.dtor]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpy2wgngo6/{from.md → to.md} +48 -46
tmp/tmpy2wgngo6/{from.md → to.md} RENAMED
@@ -1,9 +1,10 @@
1
  ### Destructors <a id="class.dtor">[[class.dtor]]</a>
2
 
3
- A *prospective destructor* is introduced by a declaration whose
4
- *declarator* is a function declarator [[dcl.fct]] of the form
 
5
 
6
  ``` bnf
7
  ptr-declarator '(' parameter-declaration-clause ')' noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ
8
  ```
9
 
@@ -14,13 +15,13 @@ parentheses, and the *id-expression* has one of the following forms:
14
  - in a *member-declaration* that belongs to the *member-specification*
15
  of a class or class template but is not a friend declaration
16
  [[class.friend]], the *id-expression* is `~`*class-name* and the
17
  *class-name* is the injected-class-name [[class.pre]] of the
18
  immediately-enclosing entity or
19
- - in a declaration at namespace scope or in a friend declaration, the
20
- *id-expression* is *nested-name-specifier* `~`*class-name* and the
21
- *class-name* names the same class as the *nested-name-specifier*.
22
 
23
  A prospective destructor shall take no arguments [[dcl.fct]]. Each
24
  *decl-specifier* of the *decl-specifier-seq* of a prospective destructor
25
  declaration (if any) shall be `friend`, `inline`, `virtual`,
26
  `constexpr`, or `consteval`.
@@ -40,21 +41,25 @@ the form
40
  At the end of the definition of a class, overload resolution is
41
  performed among the prospective destructors declared in that class with
42
  an empty argument list to select the *destructor* for the class, also
43
  known as the *selected destructor*. The program is ill-formed if
44
  overload resolution fails. Destructor selection does not constitute a
45
- reference to, or odr-use [[basic.def.odr]] of, the selected destructor,
46
  and in particular, the selected destructor may be deleted
47
  [[dcl.fct.def.delete]].
48
 
49
- The address of a destructor shall not be taken. A destructor can be
50
- invoked for a `const`, `volatile` or `const` `volatile` object. `const`
51
- and `volatile` semantics [[dcl.type.cv]] are not applied on an object
52
- under destruction. They stop being in effect when the destructor for the
53
- most derived object [[intro.object]] starts.
54
 
55
- [*Note 1*: A declaration of a destructor that does not have a
 
 
 
 
 
 
 
 
56
  *noexcept-specifier* has the same exception specification as if it had
57
  been implicitly declared [[except.spec]]. — *end note*]
58
 
59
  A defaulted destructor for a class `X` is defined as deleted if:
60
 
@@ -67,37 +72,31 @@ A defaulted destructor for a class `X` is defined as deleted if:
67
  function results in an ambiguity or in a function that is deleted or
68
  inaccessible from the defaulted destructor.
69
 
70
  A destructor is trivial if it is not user-provided and if:
71
 
72
- - the destructor is not `virtual`,
73
  - all of the direct base classes of its class have trivial destructors,
74
  and
75
  - for all of the non-static data members of its class that are of class
76
  type (or array thereof), each such class has a trivial destructor.
77
 
78
  Otherwise, the destructor is *non-trivial*.
79
 
80
- A defaulted destructor is a constexpr destructor if it satisfies the
81
- requirements for a constexpr destructor [[dcl.constexpr]].
82
-
83
- A destructor that is defaulted and not defined as deleted is *implicitly
84
- defined* when it is odr-used [[basic.def.odr]] or when it is explicitly
85
- defaulted after its first declaration.
86
 
87
  Before a defaulted destructor for a class is implicitly defined, all the
88
  non-user-provided destructors for its base classes and its non-static
89
  data members are implicitly defined.
90
 
91
- A prospective destructor can be declared `virtual` [[class.virtual]] or
92
- pure `virtual` [[class.abstract]]. If the destructor of a class is
93
- virtual and any objects of that class or any derived class are created
94
- in the program, the destructor shall be defined. If a class has a base
95
- class with a virtual destructor, its destructor (whether user- or
96
- implicitly-declared) is virtual.
97
 
98
- [*Note 2*: Some language constructs have special semantics when used
99
  during destruction; see  [[class.cdtor]]. — *end note*]
100
 
101
  After executing the body of the destructor and destroying any objects
102
  with automatic storage duration allocated within the body, a destructor
103
  for class `X` calls the destructors for `X`’s direct non-variant
@@ -105,53 +104,56 @@ non-static data members, the destructors for `X`’s non-virtual direct
105
  base classes and, if `X` is the most derived class [[class.base.init]],
106
  its destructor calls the destructors for `X`’s virtual base classes. All
107
  destructors are called as if they were referenced with a qualified name,
108
  that is, ignoring any possible virtual overriding destructors in more
109
  derived classes. Bases and members are destroyed in the reverse order of
110
- the completion of their constructor (see  [[class.base.init]]). A
111
- `return` statement [[stmt.return]] in a destructor might not directly
112
- return to the caller; before transferring control to the caller, the
113
- destructors for the members and bases are called. Destructors for
114
- elements of an array are called in reverse order of their construction
115
- (see  [[class.init]]).
 
 
 
116
 
117
  A destructor is invoked implicitly
118
 
119
  - for a constructed object with static storage duration
120
  [[basic.stc.static]] at program termination [[basic.start.term]],
121
  - for a constructed object with thread storage duration
122
  [[basic.stc.thread]] at thread exit,
123
  - for a constructed object with automatic storage duration
124
  [[basic.stc.auto]] when the block in which an object is created exits
125
  [[stmt.dcl]],
126
- - for a constructed temporary object when its lifetime ends (
127
- [[conv.rval]], [[class.temporary]]).
128
 
129
  In each case, the context of the invocation is the context of the
130
  construction of the object. A destructor may also be invoked implicitly
131
  through use of a *delete-expression* [[expr.delete]] for a constructed
132
  object allocated by a *new-expression* [[expr.new]]; the context of the
133
  invocation is the *delete-expression*.
134
 
135
- [*Note 3*: An array of class type contains several subobjects for each
136
  of which the destructor is invoked. — *end note*]
137
 
138
  A destructor can also be invoked explicitly. A destructor is
139
  *potentially invoked* if it is invoked or as specified in  [[expr.new]],
140
  [[stmt.return]], [[dcl.init.aggr]], [[class.base.init]], and 
141
  [[except.throw]]. A program is ill-formed if a destructor that is
142
  potentially invoked is deleted or not accessible from the context of the
143
  invocation.
144
 
145
  At the point of definition of a virtual destructor (including an
146
- implicit definition [[class.dtor]]), the non-array deallocation function
147
- is determined as if for the expression `delete this` appearing in a
148
- non-virtual destructor of the destructor’s class (see  [[expr.delete]]).
149
- If the lookup fails or if the deallocation function has a deleted
150
- definition [[dcl.fct.def]], the program is ill-formed.
151
 
152
- [*Note 4*: This assures that a deallocation function corresponding to
153
  the dynamic type of an object is available for the *delete-expression*
154
  [[class.free]]. — *end note*]
155
 
156
  In an explicit destructor call, the destructor is specified by a `~`
157
  followed by a *type-name* or *decltype-specifier* that denotes the
@@ -159,11 +161,11 @@ destructor’s class type. The invocation of a destructor is subject to
159
  the usual rules for member functions [[class.mfct]]; that is, if the
160
  object is not of the destructor’s class type and not of a class derived
161
  from the destructor’s class type (including when the destructor is
162
  invoked via a null pointer value), the program has undefined behavior.
163
 
164
- [*Note 5*: Invoking `delete` on a null pointer does not call the
165
  destructor; see [[expr.delete]]. — *end note*]
166
 
167
  [*Example 1*:
168
 
169
  ``` cpp
@@ -187,17 +189,17 @@ void f() {
187
  }
188
  ```
189
 
190
  — *end example*]
191
 
192
- [*Note 6*: An explicit destructor call must always be written using a
193
  member access operator [[expr.ref]] or a *qualified-id*
194
  [[expr.prim.id.qual]]; in particular, the *unary-expression* `~X()` in a
195
  member function is not an explicit destructor call
196
  [[expr.unary.op]]. — *end note*]
197
 
198
- [*Note 7*:
199
 
200
  Explicit calls of destructors are rarely needed. One use of such calls
201
  is for objects placed at specific addresses using a placement
202
  *new-expression*. Such use of explicit placement and destruction of
203
  objects can be necessary to cope with dedicated hardware resources and
@@ -219,20 +221,20 @@ void g() { // rare, specialized use:
219
  }
220
  ```
221
 
222
  — *end note*]
223
 
224
- Once a destructor is invoked for an object, the object no longer exists;
225
  the behavior is undefined if the destructor is invoked for an object
226
  whose lifetime has ended [[basic.life]].
227
 
228
  [*Example 2*: If the destructor for an object with automatic storage
229
  duration is explicitly invoked, and the block is subsequently left in a
230
  manner that would ordinarily invoke implicit destruction of the object,
231
  the behavior is undefined. — *end example*]
232
 
233
- [*Note 8*:
234
 
235
  The notation for explicit call of a destructor can be used for any
236
  scalar type name [[expr.prim.id.dtor]]. Allowing this makes it possible
237
  to write code without having to know if a destructor exists for a given
238
  type. For example:
 
1
  ### Destructors <a id="class.dtor">[[class.dtor]]</a>
2
 
3
+ A declaration whose *declarator-id* has an *unqualified-id* that begins
4
+ with a `~` declares a *prospective destructor*; its *declarator* shall
5
+ be a function declarator [[dcl.fct]] of the form
6
 
7
  ``` bnf
8
  ptr-declarator '(' parameter-declaration-clause ')' noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ
9
  ```
10
 
 
15
  - in a *member-declaration* that belongs to the *member-specification*
16
  of a class or class template but is not a friend declaration
17
  [[class.friend]], the *id-expression* is `~`*class-name* and the
18
  *class-name* is the injected-class-name [[class.pre]] of the
19
  immediately-enclosing entity or
20
+ - otherwise, the *id-expression* is *nested-name-specifier*
21
+ `~`*class-name* and the *class-name* is the injected-class-name of the
22
+ class nominated by the *nested-name-specifier*.
23
 
24
  A prospective destructor shall take no arguments [[dcl.fct]]. Each
25
  *decl-specifier* of the *decl-specifier-seq* of a prospective destructor
26
  declaration (if any) shall be `friend`, `inline`, `virtual`,
27
  `constexpr`, or `consteval`.
 
41
  At the end of the definition of a class, overload resolution is
42
  performed among the prospective destructors declared in that class with
43
  an empty argument list to select the *destructor* for the class, also
44
  known as the *selected destructor*. The program is ill-formed if
45
  overload resolution fails. Destructor selection does not constitute a
46
+ reference to, or odr-use [[term.odr.use]] of, the selected destructor,
47
  and in particular, the selected destructor may be deleted
48
  [[dcl.fct.def.delete]].
49
 
50
+ The address of a destructor shall not be taken.
 
 
 
 
51
 
52
+ [*Note 1*: A `return` statement in the body of a destructor cannot
53
+ specify a return value [[stmt.return]]. — *end note*]
54
+
55
+ A destructor can be invoked for a `const`, `volatile` or `const`
56
+ `volatile` object. `const` and `volatile` semantics [[dcl.type.cv]] are
57
+ not applied on an object under destruction. They stop being in effect
58
+ when the destructor for the most derived object [[intro.object]] starts.
59
+
60
+ [*Note 2*: A declaration of a destructor that does not have a
61
  *noexcept-specifier* has the same exception specification as if it had
62
  been implicitly declared [[except.spec]]. — *end note*]
63
 
64
  A defaulted destructor for a class `X` is defined as deleted if:
65
 
 
72
  function results in an ambiguity or in a function that is deleted or
73
  inaccessible from the defaulted destructor.
74
 
75
  A destructor is trivial if it is not user-provided and if:
76
 
77
+ - the destructor is not virtual,
78
  - all of the direct base classes of its class have trivial destructors,
79
  and
80
  - for all of the non-static data members of its class that are of class
81
  type (or array thereof), each such class has a trivial destructor.
82
 
83
  Otherwise, the destructor is *non-trivial*.
84
 
85
+ A defaulted destructor is a constexpr destructor if it is
86
+ constexpr-suitable [[dcl.constexpr]].
 
 
 
 
87
 
88
  Before a defaulted destructor for a class is implicitly defined, all the
89
  non-user-provided destructors for its base classes and its non-static
90
  data members are implicitly defined.
91
 
92
+ A prospective destructor can be declared `virtual` [[class.virtual]] and
93
+ with a *pure-specifier* [[class.abstract]]. If the destructor of a class
94
+ is virtual and any objects of that class or any derived class are
95
+ created in the program, the destructor shall be defined.
 
 
96
 
97
+ [*Note 3*: Some language constructs have special semantics when used
98
  during destruction; see  [[class.cdtor]]. — *end note*]
99
 
100
  After executing the body of the destructor and destroying any objects
101
  with automatic storage duration allocated within the body, a destructor
102
  for class `X` calls the destructors for `X`’s direct non-variant
 
104
  base classes and, if `X` is the most derived class [[class.base.init]],
105
  its destructor calls the destructors for `X`’s virtual base classes. All
106
  destructors are called as if they were referenced with a qualified name,
107
  that is, ignoring any possible virtual overriding destructors in more
108
  derived classes. Bases and members are destroyed in the reverse order of
109
+ the completion of their constructor (see  [[class.base.init]]).
110
+
111
+ [*Note 4*: A `return` statement [[stmt.return]] in a destructor might
112
+ not directly return to the caller; before transferring control to the
113
+ caller, the destructors for the members and bases are
114
+ called. — *end note*]
115
+
116
+ Destructors for elements of an array are called in reverse order of
117
+ their construction (see  [[class.init]]).
118
 
119
  A destructor is invoked implicitly
120
 
121
  - for a constructed object with static storage duration
122
  [[basic.stc.static]] at program termination [[basic.start.term]],
123
  - for a constructed object with thread storage duration
124
  [[basic.stc.thread]] at thread exit,
125
  - for a constructed object with automatic storage duration
126
  [[basic.stc.auto]] when the block in which an object is created exits
127
  [[stmt.dcl]],
128
+ - for a constructed temporary object when its lifetime ends
129
+ [[conv.rval]], [[class.temporary]].
130
 
131
  In each case, the context of the invocation is the context of the
132
  construction of the object. A destructor may also be invoked implicitly
133
  through use of a *delete-expression* [[expr.delete]] for a constructed
134
  object allocated by a *new-expression* [[expr.new]]; the context of the
135
  invocation is the *delete-expression*.
136
 
137
+ [*Note 5*: An array of class type contains several subobjects for each
138
  of which the destructor is invoked. — *end note*]
139
 
140
  A destructor can also be invoked explicitly. A destructor is
141
  *potentially invoked* if it is invoked or as specified in  [[expr.new]],
142
  [[stmt.return]], [[dcl.init.aggr]], [[class.base.init]], and 
143
  [[except.throw]]. A program is ill-formed if a destructor that is
144
  potentially invoked is deleted or not accessible from the context of the
145
  invocation.
146
 
147
  At the point of definition of a virtual destructor (including an
148
+ implicit definition), the non-array deallocation function is determined
149
+ as if for the expression `delete this` appearing in a non-virtual
150
+ destructor of the destructor’s class (see  [[expr.delete]]). If the
151
+ lookup fails or if the deallocation function has a deleted definition
152
+ [[dcl.fct.def]], the program is ill-formed.
153
 
154
+ [*Note 6*: This assures that a deallocation function corresponding to
155
  the dynamic type of an object is available for the *delete-expression*
156
  [[class.free]]. — *end note*]
157
 
158
  In an explicit destructor call, the destructor is specified by a `~`
159
  followed by a *type-name* or *decltype-specifier* that denotes the
 
161
  the usual rules for member functions [[class.mfct]]; that is, if the
162
  object is not of the destructor’s class type and not of a class derived
163
  from the destructor’s class type (including when the destructor is
164
  invoked via a null pointer value), the program has undefined behavior.
165
 
166
+ [*Note 7*: Invoking `delete` on a null pointer does not call the
167
  destructor; see [[expr.delete]]. — *end note*]
168
 
169
  [*Example 1*:
170
 
171
  ``` cpp
 
189
  }
190
  ```
191
 
192
  — *end example*]
193
 
194
+ [*Note 8*: An explicit destructor call must always be written using a
195
  member access operator [[expr.ref]] or a *qualified-id*
196
  [[expr.prim.id.qual]]; in particular, the *unary-expression* `~X()` in a
197
  member function is not an explicit destructor call
198
  [[expr.unary.op]]. — *end note*]
199
 
200
+ [*Note 9*:
201
 
202
  Explicit calls of destructors are rarely needed. One use of such calls
203
  is for objects placed at specific addresses using a placement
204
  *new-expression*. Such use of explicit placement and destruction of
205
  objects can be necessary to cope with dedicated hardware resources and
 
221
  }
222
  ```
223
 
224
  — *end note*]
225
 
226
+ Once a destructor is invoked for an object, the object’s lifetime ends;
227
  the behavior is undefined if the destructor is invoked for an object
228
  whose lifetime has ended [[basic.life]].
229
 
230
  [*Example 2*: If the destructor for an object with automatic storage
231
  duration is explicitly invoked, and the block is subsequently left in a
232
  manner that would ordinarily invoke implicit destruction of the object,
233
  the behavior is undefined. — *end example*]
234
 
235
+ [*Note 10*:
236
 
237
  The notation for explicit call of a destructor can be used for any
238
  scalar type name [[expr.prim.id.dtor]]. Allowing this makes it possible
239
  to write code without having to know if a destructor exists for a given
240
  type. For example: