- tmp/tmpugo_pmh3/{from.md → to.md} +439 -41
tmp/tmpugo_pmh3/{from.md → to.md}
RENAMED
|
@@ -34,24 +34,23 @@ struct complex {
|
|
| 34 |
complex(double,double);
|
| 35 |
};
|
| 36 |
|
| 37 |
complex sqrt(complex,complex);
|
| 38 |
|
| 39 |
-
complex a(1); //
|
| 40 |
-
complex b = a; //
|
| 41 |
-
complex c = complex(1,2); //
|
| 42 |
-
|
| 43 |
-
complex
|
| 44 |
-
complex
|
| 45 |
-
complex
|
| 46 |
-
complex g = { 1, 2 }; // initialize by a call of complex(double, double)
|
| 47 |
```
|
| 48 |
|
| 49 |
— *end example*]
|
| 50 |
|
| 51 |
-
[*Note 1*: Overloading of the assignment operator
|
| 52 |
-
|
| 53 |
|
| 54 |
An object of class type can also be initialized by a *braced-init-list*.
|
| 55 |
List-initialization semantics apply; see [[dcl.init]] and
|
| 56 |
[[dcl.init.list]].
|
| 57 |
|
|
@@ -160,11 +159,11 @@ direct non-virtual base class and an inherited virtual base class, the
|
|
| 160 |
|
| 161 |
``` cpp
|
| 162 |
struct A { A(); };
|
| 163 |
struct B: public virtual A { };
|
| 164 |
struct C: public A, public B { C(); };
|
| 165 |
-
C::C(): A() { } //
|
| 166 |
```
|
| 167 |
|
| 168 |
— *end example*]
|
| 169 |
|
| 170 |
A *ctor-initializer* may initialize a variant member of the
|
|
@@ -217,12 +216,12 @@ D d(10);
|
|
| 217 |
```
|
| 218 |
|
| 219 |
— *end example*]
|
| 220 |
|
| 221 |
[*Note 2*: The initialization performed by each *mem-initializer*
|
| 222 |
-
constitutes a full-expression
|
| 223 |
-
|
| 224 |
performs the initialization. — *end note*]
|
| 225 |
|
| 226 |
A *mem-initializer* where the *mem-initializer-id* denotes a virtual
|
| 227 |
base class is ignored during execution of a constructor of any class
|
| 228 |
that is not the most derived class.
|
|
@@ -245,27 +244,27 @@ In a non-delegating constructor, if a given potentially constructed
|
|
| 245 |
subobject is not designated by a *mem-initializer-id* (including the
|
| 246 |
case where there is no *mem-initializer-list* because the constructor
|
| 247 |
has no *ctor-initializer*), then
|
| 248 |
|
| 249 |
- if the entity is a non-static data member that has a default member
|
| 250 |
-
initializer
|
| 251 |
-
- the constructor’s class is a union
|
| 252 |
variant member of that union is designated by a *mem-initializer-id*
|
| 253 |
or
|
| 254 |
- the constructor’s class is not a union, and, if the entity is a
|
| 255 |
member of an anonymous union, no other member of that union is
|
| 256 |
designated by a *mem-initializer-id*,
|
| 257 |
|
| 258 |
the entity is initialized from its default member initializer as
|
| 259 |
specified in [[dcl.init]];
|
| 260 |
-
- otherwise, if the entity is an anonymous union or a variant member
|
| 261 |
-
[[class.union.anon]]
|
| 262 |
-
- otherwise, the entity is default-initialized
|
| 263 |
|
| 264 |
-
[*Note 3*: An abstract class
|
| 265 |
-
|
| 266 |
-
|
| 267 |
omitted. — *end note*]
|
| 268 |
|
| 269 |
An attempt to initialize more than one non-static data member of a union
|
| 270 |
renders the program ill-formed.
|
| 271 |
|
|
@@ -337,22 +336,22 @@ A a2(1); // OK, unfortunately
|
|
| 337 |
```
|
| 338 |
|
| 339 |
— *end example*]
|
| 340 |
|
| 341 |
In a non-delegating constructor, the destructor for each potentially
|
| 342 |
-
constructed subobject of class type is potentially invoked
|
| 343 |
-
[[class.dtor]]
|
| 344 |
|
| 345 |
[*Note 5*: This provision ensures that destructors can be called for
|
| 346 |
-
fully-constructed subobjects in case an exception is thrown
|
| 347 |
-
[[except.ctor]]
|
| 348 |
|
| 349 |
In a non-delegating constructor, initialization proceeds in the
|
| 350 |
following order:
|
| 351 |
|
| 352 |
-
- First, and only for the constructor of the most derived class
|
| 353 |
-
[[intro.object]]
|
| 354 |
they appear on a depth-first left-to-right traversal of the directed
|
| 355 |
acyclic graph of base classes, where “left-to-right” is the order of
|
| 356 |
appearance of the base classes in the derived class
|
| 357 |
*base-specifier-list*.
|
| 358 |
- Then, direct base classes are initialized in declaration order as they
|
|
@@ -432,16 +431,16 @@ the constructor, the `this` pointer can be used in the *expression-list*
|
|
| 432 |
of a *mem-initializer* to refer to the object being
|
| 433 |
initialized. — *end note*]
|
| 434 |
|
| 435 |
Member functions (including virtual member functions, [[class.virtual]])
|
| 436 |
can be called for an object under construction. Similarly, an object
|
| 437 |
-
under construction can be the operand of the `typeid` operator
|
| 438 |
-
[[expr.typeid]]
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
|
| 442 |
-
|
| 443 |
|
| 444 |
[*Example 11*:
|
| 445 |
|
| 446 |
``` cpp
|
| 447 |
class A {
|
|
@@ -451,11 +450,11 @@ public:
|
|
| 451 |
|
| 452 |
class B : public A {
|
| 453 |
int j;
|
| 454 |
public:
|
| 455 |
int f();
|
| 456 |
-
B() : A(f()), // undefined: calls member function but base A not yet initialized
|
| 457 |
j(f()) { } // well-defined: bases are all initialized
|
| 458 |
};
|
| 459 |
|
| 460 |
class C {
|
| 461 |
public:
|
|
@@ -463,24 +462,24 @@ public:
|
|
| 463 |
};
|
| 464 |
|
| 465 |
class D : public B, C {
|
| 466 |
int i;
|
| 467 |
public:
|
| 468 |
-
D() : C(f()), // undefined: calls member function but base C not yet initialized
|
| 469 |
i(f()) { } // well-defined: bases are all initialized
|
| 470 |
};
|
| 471 |
```
|
| 472 |
|
| 473 |
— *end example*]
|
| 474 |
|
| 475 |
[*Note 8*: [[class.cdtor]] describes the result of virtual function
|
| 476 |
calls, `typeid` and `dynamic_cast`s during construction for the
|
| 477 |
-
well-defined cases; that is, describes the
|
| 478 |
object under construction. — *end note*]
|
| 479 |
|
| 480 |
-
A *mem-initializer* followed by an ellipsis is a pack expansion
|
| 481 |
-
[[temp.variadic]]
|
| 482 |
expansion in the *base-specifier-list* for the class.
|
| 483 |
|
| 484 |
[*Example 12*:
|
| 485 |
|
| 486 |
``` cpp
|
|
@@ -494,12 +493,12 @@ public:
|
|
| 494 |
— *end example*]
|
| 495 |
|
| 496 |
### Initialization by inherited constructor <a id="class.inhctor.init">[[class.inhctor.init]]</a>
|
| 497 |
|
| 498 |
When a constructor for type `B` is invoked to initialize an object of a
|
| 499 |
-
different type `D` (that is, when the constructor was inherited
|
| 500 |
-
[[namespace.udecl]])
|
| 501 |
constructor were used to initialize the `D` object and each base class
|
| 502 |
subobject from which the constructor was inherited, except that the `B`
|
| 503 |
subobject is initialized by the invocation of the inherited constructor.
|
| 504 |
The complete initialization is considered to be a single function call;
|
| 505 |
in particular, the initialization of the inherited constructor’s
|
|
@@ -580,11 +579,11 @@ struct V2 : virtual B { using B::B; };
|
|
| 580 |
struct D2 : V1, V2 {
|
| 581 |
using V1::V1;
|
| 582 |
using V2::V2;
|
| 583 |
};
|
| 584 |
|
| 585 |
-
D1 d1(0); //
|
| 586 |
D2 d2(0); // OK: initializes virtual B base class, which initializes the A base class
|
| 587 |
// then initializes the V1 and V2 base classes as if by a defaulted default constructor
|
| 588 |
|
| 589 |
struct M { M(); M(int); };
|
| 590 |
struct N : M { using M::M; };
|
|
@@ -598,5 +597,404 @@ P p(0); // OK: use M(0) to initialize N's base class,
|
|
| 598 |
|
| 599 |
When an object is initialized by an inherited constructor,
|
| 600 |
initialization of the object is complete when the initialization of all
|
| 601 |
subobjects is complete.
|
| 602 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
complex(double,double);
|
| 35 |
};
|
| 36 |
|
| 37 |
complex sqrt(complex,complex);
|
| 38 |
|
| 39 |
+
complex a(1); // initialized by calling complex(double) with argument 1
|
| 40 |
+
complex b = a; // initialized as a copy of a
|
| 41 |
+
complex c = complex(1,2); // initialized by calling complex(double,double) with arguments 1 and 2
|
| 42 |
+
complex d = sqrt(b,c); // initialized by calling sqrt(complex,complex) with d as its result object
|
| 43 |
+
complex e; // initialized by calling complex()
|
| 44 |
+
complex f = 3; // initialized by calling complex(double) with argument 3
|
| 45 |
+
complex g = { 1, 2 }; // initialized by calling complex(double, double) with arguments 1 and 2
|
|
|
|
| 46 |
```
|
| 47 |
|
| 48 |
— *end example*]
|
| 49 |
|
| 50 |
+
[*Note 1*: Overloading of the assignment operator [[over.ass]] has no
|
| 51 |
+
effect on initialization. — *end note*]
|
| 52 |
|
| 53 |
An object of class type can also be initialized by a *braced-init-list*.
|
| 54 |
List-initialization semantics apply; see [[dcl.init]] and
|
| 55 |
[[dcl.init.list]].
|
| 56 |
|
|
|
|
| 159 |
|
| 160 |
``` cpp
|
| 161 |
struct A { A(); };
|
| 162 |
struct B: public virtual A { };
|
| 163 |
struct C: public A, public B { C(); };
|
| 164 |
+
C::C(): A() { } // error: which A?
|
| 165 |
```
|
| 166 |
|
| 167 |
— *end example*]
|
| 168 |
|
| 169 |
A *ctor-initializer* may initialize a variant member of the
|
|
|
|
| 216 |
```
|
| 217 |
|
| 218 |
— *end example*]
|
| 219 |
|
| 220 |
[*Note 2*: The initialization performed by each *mem-initializer*
|
| 221 |
+
constitutes a full-expression [[intro.execution]]. Any expression in a
|
| 222 |
+
*mem-initializer* is evaluated as part of the full-expression that
|
| 223 |
performs the initialization. — *end note*]
|
| 224 |
|
| 225 |
A *mem-initializer* where the *mem-initializer-id* denotes a virtual
|
| 226 |
base class is ignored during execution of a constructor of any class
|
| 227 |
that is not the most derived class.
|
|
|
|
| 244 |
subobject is not designated by a *mem-initializer-id* (including the
|
| 245 |
case where there is no *mem-initializer-list* because the constructor
|
| 246 |
has no *ctor-initializer*), then
|
| 247 |
|
| 248 |
- if the entity is a non-static data member that has a default member
|
| 249 |
+
initializer [[class.mem]] and either
|
| 250 |
+
- the constructor’s class is a union [[class.union]], and no other
|
| 251 |
variant member of that union is designated by a *mem-initializer-id*
|
| 252 |
or
|
| 253 |
- the constructor’s class is not a union, and, if the entity is a
|
| 254 |
member of an anonymous union, no other member of that union is
|
| 255 |
designated by a *mem-initializer-id*,
|
| 256 |
|
| 257 |
the entity is initialized from its default member initializer as
|
| 258 |
specified in [[dcl.init]];
|
| 259 |
+
- otherwise, if the entity is an anonymous union or a variant member
|
| 260 |
+
[[class.union.anon]], no initialization is performed;
|
| 261 |
+
- otherwise, the entity is default-initialized [[dcl.init]].
|
| 262 |
|
| 263 |
+
[*Note 3*: An abstract class [[class.abstract]] is never a most derived
|
| 264 |
+
class, thus its constructors never initialize virtual base classes,
|
| 265 |
+
therefore the corresponding *mem-initializer*s may be
|
| 266 |
omitted. — *end note*]
|
| 267 |
|
| 268 |
An attempt to initialize more than one non-static data member of a union
|
| 269 |
renders the program ill-formed.
|
| 270 |
|
|
|
|
| 336 |
```
|
| 337 |
|
| 338 |
— *end example*]
|
| 339 |
|
| 340 |
In a non-delegating constructor, the destructor for each potentially
|
| 341 |
+
constructed subobject of class type is potentially invoked
|
| 342 |
+
[[class.dtor]].
|
| 343 |
|
| 344 |
[*Note 5*: This provision ensures that destructors can be called for
|
| 345 |
+
fully-constructed subobjects in case an exception is thrown
|
| 346 |
+
[[except.ctor]]. — *end note*]
|
| 347 |
|
| 348 |
In a non-delegating constructor, initialization proceeds in the
|
| 349 |
following order:
|
| 350 |
|
| 351 |
+
- First, and only for the constructor of the most derived class
|
| 352 |
+
[[intro.object]], virtual base classes are initialized in the order
|
| 353 |
they appear on a depth-first left-to-right traversal of the directed
|
| 354 |
acyclic graph of base classes, where “left-to-right” is the order of
|
| 355 |
appearance of the base classes in the derived class
|
| 356 |
*base-specifier-list*.
|
| 357 |
- Then, direct base classes are initialized in declaration order as they
|
|
|
|
| 431 |
of a *mem-initializer* to refer to the object being
|
| 432 |
initialized. — *end note*]
|
| 433 |
|
| 434 |
Member functions (including virtual member functions, [[class.virtual]])
|
| 435 |
can be called for an object under construction. Similarly, an object
|
| 436 |
+
under construction can be the operand of the `typeid` operator
|
| 437 |
+
[[expr.typeid]] or of a `dynamic_cast` [[expr.dynamic.cast]]. However,
|
| 438 |
+
if these operations are performed in a *ctor-initializer* (or in a
|
| 439 |
+
function called directly or indirectly from a *ctor-initializer*) before
|
| 440 |
+
all the *mem-initializer*s for base classes have completed, the program
|
| 441 |
+
has undefined behavior.
|
| 442 |
|
| 443 |
[*Example 11*:
|
| 444 |
|
| 445 |
``` cpp
|
| 446 |
class A {
|
|
|
|
| 450 |
|
| 451 |
class B : public A {
|
| 452 |
int j;
|
| 453 |
public:
|
| 454 |
int f();
|
| 455 |
+
B() : A(f()), // undefined behavior: calls member function but base A not yet initialized
|
| 456 |
j(f()) { } // well-defined: bases are all initialized
|
| 457 |
};
|
| 458 |
|
| 459 |
class C {
|
| 460 |
public:
|
|
|
|
| 462 |
};
|
| 463 |
|
| 464 |
class D : public B, C {
|
| 465 |
int i;
|
| 466 |
public:
|
| 467 |
+
D() : C(f()), // undefined behavior: calls member function but base C not yet initialized
|
| 468 |
i(f()) { } // well-defined: bases are all initialized
|
| 469 |
};
|
| 470 |
```
|
| 471 |
|
| 472 |
— *end example*]
|
| 473 |
|
| 474 |
[*Note 8*: [[class.cdtor]] describes the result of virtual function
|
| 475 |
calls, `typeid` and `dynamic_cast`s during construction for the
|
| 476 |
+
well-defined cases; that is, describes the polymorphic behavior of an
|
| 477 |
object under construction. — *end note*]
|
| 478 |
|
| 479 |
+
A *mem-initializer* followed by an ellipsis is a pack expansion
|
| 480 |
+
[[temp.variadic]] that initializes the base classes specified by a pack
|
| 481 |
expansion in the *base-specifier-list* for the class.
|
| 482 |
|
| 483 |
[*Example 12*:
|
| 484 |
|
| 485 |
``` cpp
|
|
|
|
| 493 |
— *end example*]
|
| 494 |
|
| 495 |
### Initialization by inherited constructor <a id="class.inhctor.init">[[class.inhctor.init]]</a>
|
| 496 |
|
| 497 |
When a constructor for type `B` is invoked to initialize an object of a
|
| 498 |
+
different type `D` (that is, when the constructor was inherited
|
| 499 |
+
[[namespace.udecl]]), initialization proceeds as if a defaulted default
|
| 500 |
constructor were used to initialize the `D` object and each base class
|
| 501 |
subobject from which the constructor was inherited, except that the `B`
|
| 502 |
subobject is initialized by the invocation of the inherited constructor.
|
| 503 |
The complete initialization is considered to be a single function call;
|
| 504 |
in particular, the initialization of the inherited constructor’s
|
|
|
|
| 579 |
struct D2 : V1, V2 {
|
| 580 |
using V1::V1;
|
| 581 |
using V2::V2;
|
| 582 |
};
|
| 583 |
|
| 584 |
+
D1 d1(0); // error: ambiguous
|
| 585 |
D2 d2(0); // OK: initializes virtual B base class, which initializes the A base class
|
| 586 |
// then initializes the V1 and V2 base classes as if by a defaulted default constructor
|
| 587 |
|
| 588 |
struct M { M(); M(int); };
|
| 589 |
struct N : M { using M::M; };
|
|
|
|
| 597 |
|
| 598 |
When an object is initialized by an inherited constructor,
|
| 599 |
initialization of the object is complete when the initialization of all
|
| 600 |
subobjects is complete.
|
| 601 |
|
| 602 |
+
### Construction and destruction <a id="class.cdtor">[[class.cdtor]]</a>
|
| 603 |
+
|
| 604 |
+
For an object with a non-trivial constructor, referring to any
|
| 605 |
+
non-static member or base class of the object before the constructor
|
| 606 |
+
begins execution results in undefined behavior. For an object with a
|
| 607 |
+
non-trivial destructor, referring to any non-static member or base class
|
| 608 |
+
of the object after the destructor finishes execution results in
|
| 609 |
+
undefined behavior.
|
| 610 |
+
|
| 611 |
+
[*Example 1*:
|
| 612 |
+
|
| 613 |
+
``` cpp
|
| 614 |
+
struct X { int i; };
|
| 615 |
+
struct Y : X { Y(); }; // non-trivial
|
| 616 |
+
struct A { int a; };
|
| 617 |
+
struct B : public A { int j; Y y; }; // non-trivial
|
| 618 |
+
|
| 619 |
+
extern B bobj;
|
| 620 |
+
B* pb = &bobj; // OK
|
| 621 |
+
int* p1 = &bobj.a; // undefined behavior: refers to base class member
|
| 622 |
+
int* p2 = &bobj.y.i; // undefined behavior: refers to member's member
|
| 623 |
+
|
| 624 |
+
A* pa = &bobj; // undefined behavior: upcast to a base class type
|
| 625 |
+
B bobj; // definition of bobj
|
| 626 |
+
|
| 627 |
+
extern X xobj;
|
| 628 |
+
int* p3 = &xobj.i; // OK, X is a trivial class
|
| 629 |
+
X xobj;
|
| 630 |
+
```
|
| 631 |
+
|
| 632 |
+
For another example,
|
| 633 |
+
|
| 634 |
+
``` cpp
|
| 635 |
+
struct W { int j; };
|
| 636 |
+
struct X : public virtual W { };
|
| 637 |
+
struct Y {
|
| 638 |
+
int* p;
|
| 639 |
+
X x;
|
| 640 |
+
Y() : p(&x.j) { // undefined, x is not yet constructed
|
| 641 |
+
}
|
| 642 |
+
};
|
| 643 |
+
```
|
| 644 |
+
|
| 645 |
+
— *end example*]
|
| 646 |
+
|
| 647 |
+
During the construction of an object, if the value of the object or any
|
| 648 |
+
of its subobjects is accessed through a glvalue that is not obtained,
|
| 649 |
+
directly or indirectly, from the constructor’s `this` pointer, the value
|
| 650 |
+
of the object or subobject thus obtained is unspecified.
|
| 651 |
+
|
| 652 |
+
[*Example 2*:
|
| 653 |
+
|
| 654 |
+
``` cpp
|
| 655 |
+
struct C;
|
| 656 |
+
void no_opt(C*);
|
| 657 |
+
|
| 658 |
+
struct C {
|
| 659 |
+
int c;
|
| 660 |
+
C() : c(0) { no_opt(this); }
|
| 661 |
+
};
|
| 662 |
+
|
| 663 |
+
const C cobj;
|
| 664 |
+
|
| 665 |
+
void no_opt(C* cptr) {
|
| 666 |
+
int i = cobj.c * 100; // value of cobj.c is unspecified
|
| 667 |
+
cptr->c = 1;
|
| 668 |
+
cout << cobj.c * 100 // value of cobj.c is unspecified
|
| 669 |
+
<< '\n';
|
| 670 |
+
}
|
| 671 |
+
|
| 672 |
+
extern struct D d;
|
| 673 |
+
struct D {
|
| 674 |
+
D(int a) : a(a), b(d.a) {}
|
| 675 |
+
int a, b;
|
| 676 |
+
};
|
| 677 |
+
D d = D(1); // value of d.b is unspecified
|
| 678 |
+
```
|
| 679 |
+
|
| 680 |
+
— *end example*]
|
| 681 |
+
|
| 682 |
+
To explicitly or implicitly convert a pointer (a glvalue) referring to
|
| 683 |
+
an object of class `X` to a pointer (reference) to a direct or indirect
|
| 684 |
+
base class `B` of `X`, the construction of `X` and the construction of
|
| 685 |
+
all of its direct or indirect bases that directly or indirectly derive
|
| 686 |
+
from `B` shall have started and the destruction of these classes shall
|
| 687 |
+
not have completed, otherwise the conversion results in undefined
|
| 688 |
+
behavior. To form a pointer to (or access the value of) a direct
|
| 689 |
+
non-static member of an object `obj`, the construction of `obj` shall
|
| 690 |
+
have started and its destruction shall not have completed, otherwise the
|
| 691 |
+
computation of the pointer value (or accessing the member value) results
|
| 692 |
+
in undefined behavior.
|
| 693 |
+
|
| 694 |
+
[*Example 3*:
|
| 695 |
+
|
| 696 |
+
``` cpp
|
| 697 |
+
struct A { };
|
| 698 |
+
struct B : virtual A { };
|
| 699 |
+
struct C : B { };
|
| 700 |
+
struct D : virtual A { D(A*); };
|
| 701 |
+
struct X { X(A*); };
|
| 702 |
+
|
| 703 |
+
struct E : C, D, X {
|
| 704 |
+
E() : D(this), // undefined behavior: upcast from E* to A* might use path E* → D* → A*
|
| 705 |
+
// but D is not constructed
|
| 706 |
+
|
| 707 |
+
// ``D((C*)this)'' would be defined: E* → C* is defined because E() has started,
|
| 708 |
+
// and C* → A* is defined because C is fully constructed
|
| 709 |
+
|
| 710 |
+
X(this) {} // defined: upon construction of X, C/B/D/A sublattice is fully constructed
|
| 711 |
+
};
|
| 712 |
+
```
|
| 713 |
+
|
| 714 |
+
— *end example*]
|
| 715 |
+
|
| 716 |
+
Member functions, including virtual functions [[class.virtual]], can be
|
| 717 |
+
called during construction or destruction [[class.base.init]]. When a
|
| 718 |
+
virtual function is called directly or indirectly from a constructor or
|
| 719 |
+
from a destructor, including during the construction or destruction of
|
| 720 |
+
the class’s non-static data members, and the object to which the call
|
| 721 |
+
applies is the object (call it `x`) under construction or destruction,
|
| 722 |
+
the function called is the final overrider in the constructor’s or
|
| 723 |
+
destructor’s class and not one overriding it in a more-derived class. If
|
| 724 |
+
the virtual function call uses an explicit class member access
|
| 725 |
+
[[expr.ref]] and the object expression refers to the complete object of
|
| 726 |
+
`x` or one of that object’s base class subobjects but not `x` or one of
|
| 727 |
+
its base class subobjects, the behavior is undefined.
|
| 728 |
+
|
| 729 |
+
[*Example 4*:
|
| 730 |
+
|
| 731 |
+
``` cpp
|
| 732 |
+
struct V {
|
| 733 |
+
virtual void f();
|
| 734 |
+
virtual void g();
|
| 735 |
+
};
|
| 736 |
+
|
| 737 |
+
struct A : virtual V {
|
| 738 |
+
virtual void f();
|
| 739 |
+
};
|
| 740 |
+
|
| 741 |
+
struct B : virtual V {
|
| 742 |
+
virtual void g();
|
| 743 |
+
B(V*, A*);
|
| 744 |
+
};
|
| 745 |
+
|
| 746 |
+
struct D : A, B {
|
| 747 |
+
virtual void f();
|
| 748 |
+
virtual void g();
|
| 749 |
+
D() : B((A*)this, this) { }
|
| 750 |
+
};
|
| 751 |
+
|
| 752 |
+
B::B(V* v, A* a) {
|
| 753 |
+
f(); // calls V::f, not A::f
|
| 754 |
+
g(); // calls B::g, not D::g
|
| 755 |
+
v->g(); // v is base of B, the call is well-defined, calls B::g
|
| 756 |
+
a->f(); // undefined behavior: a's type not a base of B
|
| 757 |
+
}
|
| 758 |
+
```
|
| 759 |
+
|
| 760 |
+
— *end example*]
|
| 761 |
+
|
| 762 |
+
The `typeid` operator [[expr.typeid]] can be used during construction or
|
| 763 |
+
destruction [[class.base.init]]. When `typeid` is used in a constructor
|
| 764 |
+
(including the *mem-initializer* or default member initializer
|
| 765 |
+
[[class.mem]] for a non-static data member) or in a destructor, or used
|
| 766 |
+
in a function called (directly or indirectly) from a constructor or
|
| 767 |
+
destructor, if the operand of `typeid` refers to the object under
|
| 768 |
+
construction or destruction, `typeid` yields the `std::type_info` object
|
| 769 |
+
representing the constructor or destructor’s class. If the operand of
|
| 770 |
+
`typeid` refers to the object under construction or destruction and the
|
| 771 |
+
static type of the operand is neither the constructor or destructor’s
|
| 772 |
+
class nor one of its bases, the behavior is undefined.
|
| 773 |
+
|
| 774 |
+
`dynamic_cast`s [[expr.dynamic.cast]] can be used during construction or
|
| 775 |
+
destruction [[class.base.init]]. When a `dynamic_cast` is used in a
|
| 776 |
+
constructor (including the *mem-initializer* or default member
|
| 777 |
+
initializer for a non-static data member) or in a destructor, or used in
|
| 778 |
+
a function called (directly or indirectly) from a constructor or
|
| 779 |
+
destructor, if the operand of the `dynamic_cast` refers to the object
|
| 780 |
+
under construction or destruction, this object is considered to be a
|
| 781 |
+
most derived object that has the type of the constructor or destructor’s
|
| 782 |
+
class. If the operand of the `dynamic_cast` refers to the object under
|
| 783 |
+
construction or destruction and the static type of the operand is not a
|
| 784 |
+
pointer to or object of the constructor or destructor’s own class or one
|
| 785 |
+
of its bases, the `dynamic_cast` results in undefined behavior.
|
| 786 |
+
|
| 787 |
+
[*Example 5*:
|
| 788 |
+
|
| 789 |
+
``` cpp
|
| 790 |
+
struct V {
|
| 791 |
+
virtual void f();
|
| 792 |
+
};
|
| 793 |
+
|
| 794 |
+
struct A : virtual V { };
|
| 795 |
+
|
| 796 |
+
struct B : virtual V {
|
| 797 |
+
B(V*, A*);
|
| 798 |
+
};
|
| 799 |
+
|
| 800 |
+
struct D : A, B {
|
| 801 |
+
D() : B((A*)this, this) { }
|
| 802 |
+
};
|
| 803 |
+
|
| 804 |
+
B::B(V* v, A* a) {
|
| 805 |
+
typeid(*this); // type_info for B
|
| 806 |
+
typeid(*v); // well-defined: *v has type V, a base of B yields type_info for B
|
| 807 |
+
typeid(*a); // undefined behavior: type A not a base of B
|
| 808 |
+
dynamic_cast<B*>(v); // well-defined: v of type V*, V base of B results in B*
|
| 809 |
+
dynamic_cast<B*>(a); // undefined behavior: a has type A*, A not a base of B
|
| 810 |
+
}
|
| 811 |
+
```
|
| 812 |
+
|
| 813 |
+
— *end example*]
|
| 814 |
+
|
| 815 |
+
### Copy/move elision <a id="class.copy.elision">[[class.copy.elision]]</a>
|
| 816 |
+
|
| 817 |
+
When certain criteria are met, an implementation is allowed to omit the
|
| 818 |
+
copy/move construction of a class object, even if the constructor
|
| 819 |
+
selected for the copy/move operation and/or the destructor for the
|
| 820 |
+
object have side effects. In such cases, the implementation treats the
|
| 821 |
+
source and target of the omitted copy/move operation as simply two
|
| 822 |
+
different ways of referring to the same object. If the first parameter
|
| 823 |
+
of the selected constructor is an rvalue reference to the object’s type,
|
| 824 |
+
the destruction of that object occurs when the target would have been
|
| 825 |
+
destroyed; otherwise, the destruction occurs at the later of the times
|
| 826 |
+
when the two objects would have been destroyed without the
|
| 827 |
+
optimization.[^14] This elision of copy/move operations, called *copy
|
| 828 |
+
elision*, is permitted in the following circumstances (which may be
|
| 829 |
+
combined to eliminate multiple copies):
|
| 830 |
+
|
| 831 |
+
- in a `return` statement in a function with a class return type, when
|
| 832 |
+
the *expression* is the name of a non-volatile object with automatic
|
| 833 |
+
storage duration (other than a function parameter or a variable
|
| 834 |
+
introduced by the *exception-declaration* of a *handler*
|
| 835 |
+
[[except.handle]]) with the same type (ignoring cv-qualification) as
|
| 836 |
+
the function return type, the copy/move operation can be omitted by
|
| 837 |
+
constructing the object directly into the function call’s return
|
| 838 |
+
object
|
| 839 |
+
- in a *throw-expression* [[expr.throw]], when the operand is the name
|
| 840 |
+
of a non-volatile object with automatic storage duration (other than a
|
| 841 |
+
function or catch-clause parameter) whose scope does not extend beyond
|
| 842 |
+
the end of the innermost enclosing *try-block* (if there is one), the
|
| 843 |
+
copy/move operation can be omitted by constructing the object directly
|
| 844 |
+
into the exception object
|
| 845 |
+
- in a coroutine [[dcl.fct.def.coroutine]], a copy of a coroutine
|
| 846 |
+
parameter can be omitted and references to that copy replaced with
|
| 847 |
+
references to the corresponding parameter if the meaning of the
|
| 848 |
+
program will be unchanged except for the execution of a constructor
|
| 849 |
+
and destructor for the parameter copy object
|
| 850 |
+
- when the *exception-declaration* of an exception handler
|
| 851 |
+
[[except.pre]] declares an object of the same type (except for
|
| 852 |
+
cv-qualification) as the exception object [[except.throw]], the copy
|
| 853 |
+
operation can be omitted by treating the *exception-declaration* as an
|
| 854 |
+
alias for the exception object if the meaning of the program will be
|
| 855 |
+
unchanged except for the execution of constructors and destructors for
|
| 856 |
+
the object declared by the *exception-declaration*. \[*Note 1*: There
|
| 857 |
+
cannot be a move from the exception object because it is always an
|
| 858 |
+
lvalue. — *end note*]
|
| 859 |
+
|
| 860 |
+
Copy elision is not permitted where an expression is evaluated in a
|
| 861 |
+
context requiring a constant expression [[expr.const]] and in constant
|
| 862 |
+
initialization [[basic.start.static]].
|
| 863 |
+
|
| 864 |
+
[*Note 2*: Copy elision might be performed if the same expression is
|
| 865 |
+
evaluated in another context. — *end note*]
|
| 866 |
+
|
| 867 |
+
[*Example 1*:
|
| 868 |
+
|
| 869 |
+
``` cpp
|
| 870 |
+
class Thing {
|
| 871 |
+
public:
|
| 872 |
+
Thing();
|
| 873 |
+
~Thing();
|
| 874 |
+
Thing(const Thing&);
|
| 875 |
+
};
|
| 876 |
+
|
| 877 |
+
Thing f() {
|
| 878 |
+
Thing t;
|
| 879 |
+
return t;
|
| 880 |
+
}
|
| 881 |
+
|
| 882 |
+
Thing t2 = f();
|
| 883 |
+
|
| 884 |
+
struct A {
|
| 885 |
+
void *p;
|
| 886 |
+
constexpr A(): p(this) {}
|
| 887 |
+
};
|
| 888 |
+
|
| 889 |
+
constexpr A g() {
|
| 890 |
+
A loc;
|
| 891 |
+
return loc;
|
| 892 |
+
}
|
| 893 |
+
|
| 894 |
+
constexpr A a; // well-formed, a.p points to a
|
| 895 |
+
constexpr A b = g(); // error: b.p would be dangling[expr.const]
|
| 896 |
+
|
| 897 |
+
void h() {
|
| 898 |
+
A c = g(); // well-formed, c.p may point to c or to an ephemeral temporary
|
| 899 |
+
}
|
| 900 |
+
```
|
| 901 |
+
|
| 902 |
+
Here the criteria for elision can eliminate the copying of the object
|
| 903 |
+
`t` with automatic storage duration into the result object for the
|
| 904 |
+
function call `f()`, which is the global object `t2`. Effectively, the
|
| 905 |
+
construction of the local object `t` can be viewed as directly
|
| 906 |
+
initializing the global object `t2`, and that object’s destruction will
|
| 907 |
+
occur at program exit. Adding a move constructor to `Thing` has the same
|
| 908 |
+
effect, but it is the move construction from the object with automatic
|
| 909 |
+
storage duration to `t2` that is elided.
|
| 910 |
+
|
| 911 |
+
— *end example*]
|
| 912 |
+
|
| 913 |
+
An *implicitly movable entity* is a variable of automatic storage
|
| 914 |
+
duration that is either a non-volatile object or an rvalue reference to
|
| 915 |
+
a non-volatile object type. In the following copy-initialization
|
| 916 |
+
contexts, a move operation might be used instead of a copy operation:
|
| 917 |
+
|
| 918 |
+
- If the *expression* in a `return` [[stmt.return]] or `co_return`
|
| 919 |
+
[[stmt.return.coroutine]] statement is a (possibly parenthesized)
|
| 920 |
+
*id-expression* that names an implicitly movable entity declared in
|
| 921 |
+
the body or *parameter-declaration-clause* of the innermost enclosing
|
| 922 |
+
function or *lambda-expression*, or
|
| 923 |
+
- if the operand of a *throw-expression* [[expr.throw]] is a (possibly
|
| 924 |
+
parenthesized) *id-expression* that names an implicitly movable entity
|
| 925 |
+
whose scope does not extend beyond the *compound-statement* of the
|
| 926 |
+
innermost *try-block* or *function-try-block* (if any) whose
|
| 927 |
+
*compound-statement* or *ctor-initializer* encloses the
|
| 928 |
+
*throw-expression*,
|
| 929 |
+
|
| 930 |
+
overload resolution to select the constructor for the copy or the
|
| 931 |
+
`return_value` overload to call is first performed as if the expression
|
| 932 |
+
or operand were an rvalue. If the first overload resolution fails or was
|
| 933 |
+
not performed, overload resolution is performed again, considering the
|
| 934 |
+
expression or operand as an lvalue.
|
| 935 |
+
|
| 936 |
+
[*Note 3*: This two-stage overload resolution must be performed
|
| 937 |
+
regardless of whether copy elision will occur. It determines the
|
| 938 |
+
constructor or the `return_value` overload to be called if elision is
|
| 939 |
+
not performed, and the selected constructor or `return_value` overload
|
| 940 |
+
must be accessible even if the call is elided. — *end note*]
|
| 941 |
+
|
| 942 |
+
[*Example 2*:
|
| 943 |
+
|
| 944 |
+
``` cpp
|
| 945 |
+
class Thing {
|
| 946 |
+
public:
|
| 947 |
+
Thing();
|
| 948 |
+
~Thing();
|
| 949 |
+
Thing(Thing&&);
|
| 950 |
+
private:
|
| 951 |
+
Thing(const Thing&);
|
| 952 |
+
};
|
| 953 |
+
|
| 954 |
+
Thing f(bool b) {
|
| 955 |
+
Thing t;
|
| 956 |
+
if (b)
|
| 957 |
+
throw t; // OK: Thing(Thing&&) used (or elided) to throw t
|
| 958 |
+
return t; // OK: Thing(Thing&&) used (or elided) to return t
|
| 959 |
+
}
|
| 960 |
+
|
| 961 |
+
Thing t2 = f(false); // OK: no extra copy/move performed, t2 constructed by call to f
|
| 962 |
+
|
| 963 |
+
struct Weird {
|
| 964 |
+
Weird();
|
| 965 |
+
Weird(Weird&);
|
| 966 |
+
};
|
| 967 |
+
|
| 968 |
+
Weird g() {
|
| 969 |
+
Weird w;
|
| 970 |
+
return w; // OK: first overload resolution fails, second overload resolution selects Weird(Weird&)
|
| 971 |
+
}
|
| 972 |
+
```
|
| 973 |
+
|
| 974 |
+
— *end example*]
|
| 975 |
+
|
| 976 |
+
[*Example 3*:
|
| 977 |
+
|
| 978 |
+
``` cpp
|
| 979 |
+
template<class T> void g(const T&);
|
| 980 |
+
|
| 981 |
+
template<class T> void f() {
|
| 982 |
+
T x;
|
| 983 |
+
try {
|
| 984 |
+
T y;
|
| 985 |
+
try { g(x); }
|
| 986 |
+
catch (...) {
|
| 987 |
+
if (/*...*/)
|
| 988 |
+
throw x; // does not move
|
| 989 |
+
throw y; // moves
|
| 990 |
+
}
|
| 991 |
+
g(y);
|
| 992 |
+
} catch(...) {
|
| 993 |
+
g(x);
|
| 994 |
+
g(y); // error: y is not in scope
|
| 995 |
+
}
|
| 996 |
+
}
|
| 997 |
+
```
|
| 998 |
+
|
| 999 |
+
— *end example*]
|
| 1000 |
+
|