From Jason Turner

[class.dtor]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp3m9lxnx0/{from.md → to.md} +78 -59
tmp/tmp3m9lxnx0/{from.md → to.md} RENAMED
@@ -1,12 +1,12 @@
1
  ## Destructors <a id="class.dtor">[[class.dtor]]</a>
2
 
3
- A declaration of a destructor uses a function declarator ([[dcl.fct]])
4
- of the form
5
 
6
  ``` bnf
7
- ptr-declarator '(' parameter-declaration-clause ')' exception-specificationₒₚₜ attribute-specifier-seqₒₚₜ
8
  ```
9
 
10
  where the *ptr-declarator* consists solely of an *id-expression*, an
11
  optional *attribute-specifier-seq*, and optional surrounding
12
  parentheses, and the *id-expression* has one of the following forms:
@@ -24,24 +24,24 @@ parentheses, and the *id-expression* has one of the following forms:
24
  - in a declaration at namespace scope or in a friend declaration, the
25
  *id-expression* is *nested-name-specifier* `~`*class-name* and the
26
  *class-name* names the same class as the *nested-name-specifier*.
27
 
28
  The *class-name* shall not be a *typedef-name*. A destructor shall take
29
- no arguments ([[dcl.fct]]). In a destructor declaration, each
30
- *decl-specifier* of the optional *decl-specifier-seq* shall be `friend`,
31
- `inline`, or `virtual`.
32
 
33
  A destructor is used to destroy objects of its class type. The address
34
  of a destructor shall not be taken. A destructor can be invoked for a
35
  `const`, `volatile` or `const` `volatile` object. `const` and `volatile`
36
  semantics ([[dcl.type.cv]]) are not applied on an object under
37
  destruction. They stop being in effect when the destructor for the most
38
  derived object ([[intro.object]]) starts.
39
 
40
- A declaration of a destructor that does not have an
41
- *exception-specification* is implicitly considered to have the same
42
- *exception-specification* as an implicit declaration ([[except.spec]]).
43
 
44
  If a class has no user-declared destructor, a destructor is implicitly
45
  declared as defaulted ([[dcl.fct.def]]). An implicitly-declared
46
  destructor is an `inline` `public` member of its class.
47
 
@@ -65,41 +65,41 @@ A destructor is trivial if it is not user-provided and if:
65
  type (or array thereof), each such class has a trivial destructor.
66
 
67
  Otherwise, the destructor is *non-trivial*.
68
 
69
  A destructor that is defaulted and not defined as deleted is *implicitly
70
- defined* when it is odr-used ([[basic.def.odr]]) to destroy an object
71
- of its class type ([[basic.stc]]) or when it is explicitly defaulted
72
- after its first declaration.
73
 
74
  Before the defaulted destructor for a class is implicitly defined, all
75
  the non-user-provided destructors for its base classes and its
76
  non-static data members shall have been implicitly defined.
77
 
78
  After executing the body of the destructor and destroying any automatic
79
  objects allocated within the body, a destructor for class `X` calls the
80
  destructors for `X`’s direct non-variant non-static data members, the
81
- destructors for `X`’s direct base classes and, if `X` is the type of the
82
- most derived class ([[class.base.init]]), its destructor calls the
83
- destructors for `X`’s virtual base classes. All destructors are called
84
- as if they were referenced with a qualified name, that is, ignoring any
85
- possible virtual overriding destructors in more derived classes. Bases
86
- and members are destroyed in the reverse order of the completion of
87
- their constructor (see  [[class.base.init]]). A `return` statement (
88
- [[stmt.return]]) in a destructor might not directly return to the
89
- caller; before transferring control to the caller, the destructors for
90
- the members and bases are called. Destructors for elements of an array
91
- are called in reverse order of their construction (see  [[class.init]]).
 
92
 
93
  A destructor can be declared `virtual` ([[class.virtual]]) or pure
94
  `virtual` ([[class.abstract]]); if any objects of that class or any
95
  derived class are created in the program, the destructor shall be
96
  defined. If a class has a base class with a virtual destructor, its
97
  destructor (whether user- or implicitly-declared) is virtual.
98
 
99
- some language constructs have special semantics when used during
100
- destruction; see  [[class.cdtor]].
101
 
102
  A destructor is invoked implicitly
103
 
104
  - for a constructed object with static storage duration (
105
  [[basic.stc.static]]) at program termination ([[basic.start.term]]),
@@ -107,44 +107,50 @@ A destructor is invoked implicitly
107
  [[basic.stc.thread]]) at thread exit,
108
  - for a constructed object with automatic storage duration (
109
  [[basic.stc.auto]]) when the block in which an object is created
110
  exits ([[stmt.dcl]]),
111
  - for a constructed temporary object when its lifetime ends (
112
- [[class.temporary]]).
113
 
114
  In each case, the context of the invocation is the context of the
115
  construction of the object. A destructor is also invoked implicitly
116
  through use of a *delete-expression* ([[expr.delete]]) for a
117
  constructed object allocated by a *new-expression* ([[expr.new]]); the
118
- context of the invocation is the *delete-expression*. An array of class
119
- type contains several subobjects for each of which the destructor is
120
- invoked. A destructor can also be invoked explicitly. A destructor is
121
- *potentially invoked* if it is invoked or as specified in  [[expr.new]]
122
- and  [[class.base.init]]. A program is ill-formed if a destructor that
123
- is potentially invoked is deleted or not accessible from the context of
124
- the invocation.
 
 
 
125
 
126
  At the point of definition of a virtual destructor (including an
127
  implicit definition ([[class.copy]])), the non-array deallocation
128
- function is looked up in the scope of the destructor’s class (
129
- [[class.member.lookup]]), and, if no declaration is found, the function
130
- is looked up in the global scope. If the result of this lookup is
131
- ambiguous or inaccessible, or if the lookup selects a placement
132
- deallocation function or a function with a deleted definition (
133
- [[dcl.fct.def]]), the program is ill-formed. This assures that a
134
- deallocation function corresponding to the dynamic type of an object is
135
- available for the *delete-expression* ([[class.free]]).
136
 
137
- In an explicit destructor call, the destructor name appears as a `~`
 
 
 
 
138
  followed by a *type-name* or *decltype-specifier* that denotes the
139
  destructor’s class type. The invocation of a destructor is subject to
140
  the usual rules for member functions ([[class.mfct]]); that is, if the
141
  object is not of the destructor’s class type and not of a class derived
142
  from the destructor’s class type (including when the destructor is
143
  invoked via a null pointer value), the program has undefined behavior.
144
- invoking `delete` on a null pointer does not call the destructor; see
145
- [[expr.delete]].
 
 
 
146
 
147
  ``` cpp
148
  struct B {
149
  virtual ~B() { }
150
  };
@@ -163,20 +169,25 @@ void f() {
163
  B_ptr->B_alias::~B(); // calls B's destructor
164
  B_ptr->B_alias::~B_alias(); // calls B's destructor
165
  }
166
  ```
167
 
168
- An explicit destructor call must always be written using a member access
169
- operator ([[expr.ref]]) or a qualified-id ([[expr.prim]]); in
170
- particular, the *unary-expression* `~X()` in a member function is not an
171
- explicit destructor call ([[expr.unary.op]]).
172
 
173
- explicit calls of destructors are rarely needed. One use of such calls
174
- is for objects placed at specific addresses using a *new-expression*
175
- with the placement option. Such use of explicit placement and
176
- destruction of objects can be necessary to cope with dedicated hardware
177
- resources and for writing memory management facilities. For example,
 
 
 
 
 
 
 
 
178
 
179
  ``` cpp
180
  void* operator new(std::size_t, void* p) { return p; }
181
  struct X {
182
  X(int);
@@ -190,23 +201,31 @@ void g() { // rare, specialized use:
190
  f(p);
191
  p->X::~X(); // cleanup
192
  }
193
  ```
194
 
 
 
195
  Once a destructor is invoked for an object, the object no longer exists;
196
  the behavior is undefined if the destructor is invoked for an object
197
- whose lifetime has ended ([[basic.life]]). if the destructor for an
198
- automatic object is explicitly invoked, and the block is subsequently
199
- left in a manner that would ordinarily invoke implicit destruction of
200
- the object, the behavior is undefined.
201
 
202
- the notation for explicit call of a destructor can be used for any
 
 
 
 
 
 
 
203
  scalar type name ([[expr.pseudo]]). Allowing this makes it possible to
204
  write code without having to know if a destructor exists for a given
205
- type. For example,
206
 
207
  ``` cpp
208
  typedef int I;
209
  I* p;
210
  p->I::~I();
211
  ```
212
 
 
 
 
1
  ## Destructors <a id="class.dtor">[[class.dtor]]</a>
2
 
3
+ In a declaration of a destructor, the *declarator* is a function
4
+ declarator ([[dcl.fct]]) of the form
5
 
6
  ``` bnf
7
+ ptr-declarator '(' parameter-declaration-clause ')' noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ
8
  ```
9
 
10
  where the *ptr-declarator* consists solely of an *id-expression*, an
11
  optional *attribute-specifier-seq*, and optional surrounding
12
  parentheses, and the *id-expression* has one of the following forms:
 
24
  - in a declaration at namespace scope or in a friend declaration, the
25
  *id-expression* is *nested-name-specifier* `~`*class-name* and the
26
  *class-name* names the same class as the *nested-name-specifier*.
27
 
28
  The *class-name* shall not be a *typedef-name*. A destructor shall take
29
+ no arguments ([[dcl.fct]]). Each *decl-specifier* of the
30
+ *decl-specifier-seq* of a destructor declaration (if any) shall be
31
+ `friend`, `inline`, or `virtual`.
32
 
33
  A destructor is used to destroy objects of its class type. The address
34
  of a destructor shall not be taken. A destructor can be invoked for a
35
  `const`, `volatile` or `const` `volatile` object. `const` and `volatile`
36
  semantics ([[dcl.type.cv]]) are not applied on an object under
37
  destruction. They stop being in effect when the destructor for the most
38
  derived object ([[intro.object]]) starts.
39
 
40
+ [*Note 1*: A declaration of a destructor that does not have a
41
+ *noexcept-specifier* has the same exception specification as if had been
42
+ implicitly declared ([[except.spec]]). — *end note*]
43
 
44
  If a class has no user-declared destructor, a destructor is implicitly
45
  declared as defaulted ([[dcl.fct.def]]). An implicitly-declared
46
  destructor is an `inline` `public` member of its class.
47
 
 
65
  type (or array thereof), each such class has a trivial destructor.
66
 
67
  Otherwise, the destructor is *non-trivial*.
68
 
69
  A destructor that is defaulted and not defined as deleted is *implicitly
70
+ defined* when it is odr-used ([[basic.def.odr]]) or when it is
71
+ explicitly defaulted after its first declaration.
 
72
 
73
  Before the defaulted destructor for a class is implicitly defined, all
74
  the non-user-provided destructors for its base classes and its
75
  non-static data members shall have been implicitly defined.
76
 
77
  After executing the body of the destructor and destroying any automatic
78
  objects allocated within the body, a destructor for class `X` calls the
79
  destructors for `X`’s direct non-variant non-static data members, the
80
+ destructors for `X`’s non-virtual direct base classes and, if `X` is the
81
+ type of the most derived class ([[class.base.init]]), its destructor
82
+ calls the destructors for `X`’s virtual base classes. All destructors
83
+ are called as if they were referenced with a qualified name, that is,
84
+ ignoring any possible virtual overriding destructors in more derived
85
+ classes. Bases and members are destroyed in the reverse order of the
86
+ completion of their constructor (see  [[class.base.init]]). A `return`
87
+ statement ([[stmt.return]]) in a destructor might not directly return
88
+ to the caller; before transferring control to the caller, the
89
+ destructors for the members and bases are called. Destructors for
90
+ elements of an array are called in reverse order of their construction
91
+ (see  [[class.init]]).
92
 
93
  A destructor can be declared `virtual` ([[class.virtual]]) or pure
94
  `virtual` ([[class.abstract]]); if any objects of that class or any
95
  derived class are created in the program, the destructor shall be
96
  defined. If a class has a base class with a virtual destructor, its
97
  destructor (whether user- or implicitly-declared) is virtual.
98
 
99
+ [*Note 2*: Some language constructs have special semantics when used
100
+ during destruction; see  [[class.cdtor]]. — *end note*]
101
 
102
  A destructor is invoked implicitly
103
 
104
  - for a constructed object with static storage duration (
105
  [[basic.stc.static]]) at program termination ([[basic.start.term]]),
 
107
  [[basic.stc.thread]]) at thread exit,
108
  - for a constructed object with automatic storage duration (
109
  [[basic.stc.auto]]) when the block in which an object is created
110
  exits ([[stmt.dcl]]),
111
  - for a constructed temporary object when its lifetime ends (
112
+ [[conv.rval]], [[class.temporary]]).
113
 
114
  In each case, the context of the invocation is the context of the
115
  construction of the object. A destructor is also invoked implicitly
116
  through use of a *delete-expression* ([[expr.delete]]) for a
117
  constructed object allocated by a *new-expression* ([[expr.new]]); the
118
+ context of the invocation is the *delete-expression*.
119
+
120
+ [*Note 3*: An array of class type contains several subobjects for each
121
+ of which the destructor is invoked. *end note*]
122
+
123
+ A destructor can also be invoked explicitly. A destructor is
124
+ *potentially invoked* if it is invoked or as specified in  [[expr.new]],
125
+ [[class.base.init]], and  [[except.throw]]. A program is ill-formed if a
126
+ destructor that is potentially invoked is deleted or not accessible from
127
+ the context of the invocation.
128
 
129
  At the point of definition of a virtual destructor (including an
130
  implicit definition ([[class.copy]])), the non-array deallocation
131
+ function is determined as if for the expression `delete this` appearing
132
+ in a non-virtual destructor of the destructor’s class (see 
133
+ [[expr.delete]]). If the lookup fails or if the deallocation function
134
+ has a deleted definition ([[dcl.fct.def]]), the program is ill-formed.
 
 
 
 
135
 
136
+ [*Note 4*: This assures that a deallocation function corresponding to
137
+ the dynamic type of an object is available for the *delete-expression* (
138
+ [[class.free]]). — *end note*]
139
+
140
+ In an explicit destructor call, the destructor is specified by a `~`
141
  followed by a *type-name* or *decltype-specifier* that denotes the
142
  destructor’s class type. The invocation of a destructor is subject to
143
  the usual rules for member functions ([[class.mfct]]); that is, if the
144
  object is not of the destructor’s class type and not of a class derived
145
  from the destructor’s class type (including when the destructor is
146
  invoked via a null pointer value), the program has undefined behavior.
147
+
148
+ [*Note 5*: Invoking `delete` on a null pointer does not call the
149
+ destructor; see [[expr.delete]]. — *end note*]
150
+
151
+ [*Example 1*:
152
 
153
  ``` cpp
154
  struct B {
155
  virtual ~B() { }
156
  };
 
169
  B_ptr->B_alias::~B(); // calls B's destructor
170
  B_ptr->B_alias::~B_alias(); // calls B's destructor
171
  }
172
  ```
173
 
174
+ *end example*]
 
 
 
175
 
176
+ [*Note 6*: An explicit destructor call must always be written using a
177
+ member access operator ([[expr.ref]]) or a *qualified-id* (
178
+ [[expr.prim]]); in particular, the *unary-expression* `~X()` in a member
179
+ function is not an explicit destructor call (
180
+ [[expr.unary.op]]). *end note*]
181
+
182
+ [*Note 7*:
183
+
184
+ Explicit calls of destructors are rarely needed. One use of such calls
185
+ is for objects placed at specific addresses using a placement
186
+ *new-expression*. Such use of explicit placement and destruction of
187
+ objects can be necessary to cope with dedicated hardware resources and
188
+ for writing memory management facilities. For example,
189
 
190
  ``` cpp
191
  void* operator new(std::size_t, void* p) { return p; }
192
  struct X {
193
  X(int);
 
201
  f(p);
202
  p->X::~X(); // cleanup
203
  }
204
  ```
205
 
206
+ — *end note*]
207
+
208
  Once a destructor is invoked for an object, the object no longer exists;
209
  the behavior is undefined if the destructor is invoked for an object
210
+ whose lifetime has ended ([[basic.life]]).
 
 
 
211
 
212
+ [*Example 2*: If the destructor for an automatic object is explicitly
213
+ invoked, and the block is subsequently left in a manner that would
214
+ ordinarily invoke implicit destruction of the object, the behavior is
215
+ undefined. — *end example*]
216
+
217
+ [*Note 8*:
218
+
219
+ The notation for explicit call of a destructor can be used for any
220
  scalar type name ([[expr.pseudo]]). Allowing this makes it possible to
221
  write code without having to know if a destructor exists for a given
222
+ type. For example:
223
 
224
  ``` cpp
225
  typedef int I;
226
  I* p;
227
  p->I::~I();
228
  ```
229
 
230
+ — *end note*]
231
+