From Jason Turner

[class.free]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpr4mvwd5r/{from.md → to.md} +6 -267
tmp/tmpr4mvwd5r/{from.md → to.md} RENAMED
@@ -1,6 +1,6 @@
1
- ## Free store <a id="class.free">[[class.free]]</a>
2
 
3
  Any allocation function for a class `T` is a static member (even if not
4
  explicitly declared `static`).
5
 
6
  [*Example 1*:
@@ -21,28 +21,10 @@ void foo(int i) {
21
  }
22
  ```
23
 
24
  — *end example*]
25
 
26
- When an object is deleted with a *delete-expression* [[expr.delete]], a
27
- deallocation function (`operator delete()` for non-array objects or
28
- `operator delete[]()` for arrays) is (implicitly) called to reclaim the
29
- storage occupied by the object [[basic.stc.dynamic.deallocation]].
30
-
31
- Class-specific deallocation function lookup is a part of general
32
- deallocation function lookup [[expr.delete]] and occurs as follows. If
33
- the *delete-expression* is used to deallocate a class object whose
34
- static type has a virtual destructor, the deallocation function is the
35
- one selected at the point of definition of the dynamic type’s virtual
36
- destructor [[class.dtor]].[^15] Otherwise, if the *delete-expression* is
37
- used to deallocate an object of class `T` or array thereof, the
38
- deallocation function’s name is looked up in the scope of `T`. If this
39
- lookup fails to find the name, general deallocation function lookup
40
- [[expr.delete]] continues. If the result of the lookup is ambiguous or
41
- inaccessible, or if the lookup selects a placement deallocation
42
- function, the program is ill-formed.
43
-
44
  Any deallocation function for a class `X` is a static member (even if
45
  not explicitly declared `static`).
46
 
47
  [*Example 2*:
48
 
@@ -64,14 +46,13 @@ Since member allocation and deallocation functions are `static` they
64
  cannot be virtual.
65
 
66
  [*Note 1*:
67
 
68
  However, when the *cast-expression* of a *delete-expression* refers to
69
- an object of class type, because the deallocation function actually
70
- called is looked up in the scope of the class that is the dynamic type
71
- of the object if the destructor is virtual, the effect is the same in
72
- that case. For example,
73
 
74
  ``` cpp
75
  struct B {
76
  virtual ~B();
77
  void operator delete(void*, std::size_t);
@@ -129,258 +110,16 @@ void f(int i) {
129
  }
130
  ```
131
 
132
  — *end note*]
133
 
134
- Access to the deallocation function is checked statically. Hence, even
135
- though a different one might actually be executed, the statically
136
- visible deallocation function is required to be accessible.
137
 
138
  [*Example 3*: For the call on line “// 1” above, if
139
  `B::operator delete()` had been private, the delete expression would
140
  have been ill-formed. — *end example*]
141
 
142
  [*Note 3*: If a deallocation function has no explicit
143
  *noexcept-specifier*, it has a non-throwing exception specification
144
  [[except.spec]]. — *end note*]
145
 
146
- <!-- Link reference definitions -->
147
- [basic.compound]: basic.md#basic.compound
148
- [basic.def]: basic.md#basic.def
149
- [basic.def.odr]: basic.md#basic.def.odr
150
- [basic.life]: basic.md#basic.life
151
- [basic.link]: basic.md#basic.link
152
- [basic.lookup]: basic.md#basic.lookup
153
- [basic.lookup.elab]: basic.md#basic.lookup.elab
154
- [basic.lookup.qual]: basic.md#basic.lookup.qual
155
- [basic.lookup.unqual]: basic.md#basic.lookup.unqual
156
- [basic.lval]: expr.md#basic.lval
157
- [basic.scope]: basic.md#basic.scope
158
- [basic.scope.class]: basic.md#basic.scope.class
159
- [basic.scope.hiding]: basic.md#basic.scope.hiding
160
- [basic.start.dynamic]: basic.md#basic.start.dynamic
161
- [basic.start.static]: basic.md#basic.start.static
162
- [basic.start.term]: basic.md#basic.start.term
163
- [basic.stc]: basic.md#basic.stc
164
- [basic.stc.auto]: basic.md#basic.stc.auto
165
- [basic.stc.dynamic]: basic.md#basic.stc.dynamic
166
- [basic.stc.dynamic.deallocation]: basic.md#basic.stc.dynamic.deallocation
167
- [basic.stc.static]: basic.md#basic.stc.static
168
- [basic.stc.thread]: basic.md#basic.stc.thread
169
- [basic.type.qualifier]: basic.md#basic.type.qualifier
170
- [basic.types]: basic.md#basic.types
171
- [class]: #class
172
- [class.abstract]: #class.abstract
173
- [class.access]: #class.access
174
- [class.access.base]: #class.access.base
175
- [class.access.nest]: #class.access.nest
176
- [class.access.spec]: #class.access.spec
177
- [class.access.virt]: #class.access.virt
178
- [class.base.init]: #class.base.init
179
- [class.bit]: #class.bit
180
- [class.cdtor]: #class.cdtor
181
- [class.compare]: #class.compare
182
- [class.compare.default]: #class.compare.default
183
- [class.compare.secondary]: #class.compare.secondary
184
- [class.conv]: #class.conv
185
- [class.conv.ctor]: #class.conv.ctor
186
- [class.conv.fct]: #class.conv.fct
187
- [class.copy.assign]: #class.copy.assign
188
- [class.copy.ctor]: #class.copy.ctor
189
- [class.copy.elision]: #class.copy.elision
190
- [class.ctor]: #class.ctor
191
- [class.default.ctor]: #class.default.ctor
192
- [class.derived]: #class.derived
193
- [class.dtor]: #class.dtor
194
- [class.eq]: #class.eq
195
- [class.expl.init]: #class.expl.init
196
- [class.free]: #class.free
197
- [class.friend]: #class.friend
198
- [class.inhctor.init]: #class.inhctor.init
199
- [class.init]: #class.init
200
- [class.local]: #class.local
201
- [class.mem]: #class.mem
202
- [class.member.lookup]: #class.member.lookup
203
- [class.mfct]: #class.mfct
204
- [class.mfct.non-static]: #class.mfct.non-static
205
- [class.mi]: #class.mi
206
- [class.name]: #class.name
207
- [class.nest]: #class.nest
208
- [class.nested.type]: #class.nested.type
209
- [class.paths]: #class.paths
210
- [class.pre]: #class.pre
211
- [class.prop]: #class.prop
212
- [class.protected]: #class.protected
213
- [class.qual]: basic.md#class.qual
214
- [class.spaceship]: #class.spaceship
215
- [class.static]: #class.static
216
- [class.static.data]: #class.static.data
217
- [class.static.mfct]: #class.static.mfct
218
- [class.temporary]: basic.md#class.temporary
219
- [class.this]: #class.this
220
- [class.union]: #class.union
221
- [class.union.anon]: #class.union.anon
222
- [class.virtual]: #class.virtual
223
- [cmp.categories]: support.md#cmp.categories
224
- [cmp.categories.pre]: support.md#cmp.categories.pre
225
- [cmp.partialord]: support.md#cmp.partialord
226
- [cmp.strongord]: support.md#cmp.strongord
227
- [cmp.weakord]: support.md#cmp.weakord
228
- [conv]: expr.md#conv
229
- [conv.mem]: expr.md#conv.mem
230
- [conv.ptr]: expr.md#conv.ptr
231
- [conv.rval]: expr.md#conv.rval
232
- [dcl.array]: dcl.md#dcl.array
233
- [dcl.attr.nouniqueaddr]: dcl.md#dcl.attr.nouniqueaddr
234
- [dcl.constexpr]: dcl.md#dcl.constexpr
235
- [dcl.decl]: dcl.md#dcl.decl
236
- [dcl.enum]: dcl.md#dcl.enum
237
- [dcl.fct]: dcl.md#dcl.fct
238
- [dcl.fct.def]: dcl.md#dcl.fct.def
239
- [dcl.fct.def.coroutine]: dcl.md#dcl.fct.def.coroutine
240
- [dcl.fct.def.delete]: dcl.md#dcl.fct.def.delete
241
- [dcl.fct.def.general]: dcl.md#dcl.fct.def.general
242
- [dcl.fct.default]: dcl.md#dcl.fct.default
243
- [dcl.fct.spec]: dcl.md#dcl.fct.spec
244
- [dcl.init]: dcl.md#dcl.init
245
- [dcl.init.aggr]: dcl.md#dcl.init.aggr
246
- [dcl.init.list]: dcl.md#dcl.init.list
247
- [dcl.init.ref]: dcl.md#dcl.init.ref
248
- [dcl.inline]: dcl.md#dcl.inline
249
- [dcl.spec.auto]: dcl.md#dcl.spec.auto
250
- [dcl.stc]: dcl.md#dcl.stc
251
- [dcl.type.cv]: dcl.md#dcl.type.cv
252
- [dcl.type.elab]: dcl.md#dcl.type.elab
253
- [dcl.type.simple]: dcl.md#dcl.type.simple
254
- [dcl.typedef]: dcl.md#dcl.typedef
255
- [depr.impldec]: future.md#depr.impldec
256
- [depr.static.constexpr]: future.md#depr.static.constexpr
257
- [diff.class]: compatibility.md#diff.class
258
- [except.ctor]: except.md#except.ctor
259
- [except.handle]: except.md#except.handle
260
- [except.pre]: except.md#except.pre
261
- [except.spec]: except.md#except.spec
262
- [except.throw]: except.md#except.throw
263
- [expr.ass]: expr.md#expr.ass
264
- [expr.call]: expr.md#expr.call
265
- [expr.cast]: expr.md#expr.cast
266
- [expr.const]: expr.md#expr.const
267
- [expr.const.cast]: expr.md#expr.const.cast
268
- [expr.delete]: expr.md#expr.delete
269
- [expr.dynamic.cast]: expr.md#expr.dynamic.cast
270
- [expr.eq]: expr.md#expr.eq
271
- [expr.new]: expr.md#expr.new
272
- [expr.prim.id]: expr.md#expr.prim.id
273
- [expr.prim.id.dtor]: expr.md#expr.prim.id.dtor
274
- [expr.prim.id.qual]: expr.md#expr.prim.id.qual
275
- [expr.prim.this]: expr.md#expr.prim.this
276
- [expr.ref]: expr.md#expr.ref
277
- [expr.reinterpret.cast]: expr.md#expr.reinterpret.cast
278
- [expr.rel]: expr.md#expr.rel
279
- [expr.static.cast]: expr.md#expr.static.cast
280
- [expr.sub]: expr.md#expr.sub
281
- [expr.throw]: expr.md#expr.throw
282
- [expr.type.conv]: expr.md#expr.type.conv
283
- [expr.typeid]: expr.md#expr.typeid
284
- [expr.unary.op]: expr.md#expr.unary.op
285
- [intro.execution]: basic.md#intro.execution
286
- [intro.object]: basic.md#intro.object
287
- [namespace.def]: dcl.md#namespace.def
288
- [namespace.memdef]: dcl.md#namespace.memdef
289
- [namespace.udecl]: dcl.md#namespace.udecl
290
- [over]: over.md#over
291
- [over.ass]: over.md#over.ass
292
- [over.best.ics]: over.md#over.best.ics
293
- [over.binary]: over.md#over.binary
294
- [over.ics.ref]: over.md#over.ics.ref
295
- [over.load]: over.md#over.load
296
- [over.match]: over.md#over.match
297
- [over.match.best]: over.md#over.match.best
298
- [over.match.call]: over.md#over.match.call
299
- [over.match.copy]: over.md#over.match.copy
300
- [over.match.funcs]: over.md#over.match.funcs
301
- [over.oper]: over.md#over.oper
302
- [over.over]: over.md#over.over
303
- [special]: #special
304
- [stmt.dcl]: stmt.md#stmt.dcl
305
- [stmt.return]: stmt.md#stmt.return
306
- [stmt.return.coroutine]: stmt.md#stmt.return.coroutine
307
- [string.classes]: strings.md#string.classes
308
- [temp.arg]: temp.md#temp.arg
309
- [temp.class.spec]: temp.md#temp.class.spec
310
- [temp.constr]: temp.md#temp.constr
311
- [temp.constr.order]: temp.md#temp.constr.order
312
- [temp.dep.type]: temp.md#temp.dep.type
313
- [temp.expl.spec]: temp.md#temp.expl.spec
314
- [temp.friend]: temp.md#temp.friend
315
- [temp.inst]: temp.md#temp.inst
316
- [temp.mem]: temp.md#temp.mem
317
- [temp.param]: temp.md#temp.param
318
- [temp.pre]: temp.md#temp.pre
319
- [temp.spec]: temp.md#temp.spec
320
- [temp.variadic]: temp.md#temp.variadic
321
-
322
- [^1]: This ensures that two subobjects that have the same class type and
323
- that belong to the same most derived object are not allocated at the
324
- same address [[expr.eq]].
325
-
326
- [^2]: See, for example, `<cstring>`.
327
-
328
- [^3]: This implies that the reference parameter of the
329
- implicitly-declared copy constructor cannot bind to a `volatile`
330
- lvalue; see  [[diff.class]].
331
-
332
- [^4]: Because a template assignment operator or an assignment operator
333
- taking an rvalue reference parameter is never a copy assignment
334
- operator, the presence of such an assignment operator does not
335
- suppress the implicit declaration of a copy assignment operator.
336
- Such assignment operators participate in overload resolution with
337
- other assignment operators, including copy assignment operators,
338
- and, if selected, will be used to assign an object.
339
-
340
- [^5]: This implies that the reference parameter of the
341
- implicitly-declared copy assignment operator cannot bind to a
342
- `volatile` lvalue; see  [[diff.class]].
343
-
344
- [^6]: These conversions are considered as standard conversions for the
345
- purposes of overload resolution ([[over.best.ics]],
346
- [[over.ics.ref]]) and therefore initialization [[dcl.init]] and
347
- explicit casts [[expr.static.cast]]. A conversion to `void` does not
348
- invoke any conversion function [[expr.static.cast]]. Even though
349
- never directly called to perform a conversion, such conversion
350
- functions can be declared and can potentially be reached through a
351
- call to a virtual conversion function in a base class.
352
-
353
- [^7]: The use of the `virtual` specifier in the declaration of an
354
- overriding function is valid but redundant (has empty semantics).
355
-
356
- [^8]: If all virtual functions are immediate functions, the class is
357
- still polymorphic even though its internal representation might not
358
- otherwise require any additions for that polymorphic behavior.
359
-
360
- [^9]: A function with the same name but a different parameter list
361
- [[over]] as a virtual function is not necessarily virtual and does
362
- not override. Access control [[class.access]] is not considered in
363
- determining overriding.
364
-
365
- [^10]: Multi-level pointers to classes or references to multi-level
366
- pointers to classes are not allowed.
367
-
368
- [^11]: Access permissions are thus transitive and cumulative to nested
369
- and local classes.
370
-
371
- [^12]: As specified previously in [[class.access]], private members of a
372
- base class remain inaccessible even to derived classes unless friend
373
- declarations within the base class definition are used to grant
374
- access explicitly.
375
-
376
- [^13]: This additional check does not apply to other members, e.g.,
377
- static data members or enumerator member constants.
378
-
379
- [^14]: Because only one object is destroyed instead of two, and one
380
- copy/move constructor is not executed, there is still one object
381
- destroyed for each one constructed.
382
-
383
- [^15]: A similar provision is not needed for the array version of
384
- `operator` `delete` because  [[expr.delete]] requires that in this
385
- situation, the static type of the object to be deleted be the same
386
- as its dynamic type.
 
1
+ ### Allocation and deallocation functions <a id="class.free">[[class.free]]</a>
2
 
3
  Any allocation function for a class `T` is a static member (even if not
4
  explicitly declared `static`).
5
 
6
  [*Example 1*:
 
21
  }
22
  ```
23
 
24
  — *end example*]
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  Any deallocation function for a class `X` is a static member (even if
27
  not explicitly declared `static`).
28
 
29
  [*Example 2*:
30
 
 
46
  cannot be virtual.
47
 
48
  [*Note 1*:
49
 
50
  However, when the *cast-expression* of a *delete-expression* refers to
51
+ an object of class type with a virtual destructor, because the
52
+ deallocation function is chosen by the destructor of the dynamic type of
53
+ the object, the effect is the same in that case. For example,
 
54
 
55
  ``` cpp
56
  struct B {
57
  virtual ~B();
58
  void operator delete(void*, std::size_t);
 
110
  }
111
  ```
112
 
113
  — *end note*]
114
 
115
+ Access to the deallocation function is checked statically, even if a
116
+ different one is actually executed.
 
117
 
118
  [*Example 3*: For the call on line “// 1” above, if
119
  `B::operator delete()` had been private, the delete expression would
120
  have been ill-formed. — *end example*]
121
 
122
  [*Note 3*: If a deallocation function has no explicit
123
  *noexcept-specifier*, it has a non-throwing exception specification
124
  [[except.spec]]. — *end note*]
125