From Jason Turner

[class.cdtor]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp_kffhkrf/{from.md → to.md} +38 -29
tmp/tmp_kffhkrf/{from.md → to.md} RENAMED
@@ -5,10 +5,12 @@ non-static member or base class of the object before the constructor
5
  begins execution results in undefined behavior. For an object with a
6
  non-trivial destructor, referring to any non-static member or base class
7
  of the object after the destructor finishes execution results in
8
  undefined behavior.
9
 
 
 
10
  ``` cpp
11
  struct X { int i; };
12
  struct Y : X { Y(); }; // non-trivial
13
  struct A { int a; };
14
  struct B : public A { int j; Y y; }; // non-trivial
@@ -37,10 +39,12 @@ struct Y {
37
  Y() : p(&x.j) { // undefined, x is not yet constructed
38
  }
39
  };
40
  ```
41
 
 
 
42
  To explicitly or implicitly convert a pointer (a glvalue) referring to
43
  an object of class `X` to a pointer (reference) to a direct or indirect
44
  base class `B` of `X`, the construction of `X` and the construction of
45
  all of its direct or indirect bases that directly or indirectly derive
46
  from `B` shall have started and the destruction of these classes shall
@@ -49,31 +53,32 @@ behavior. To form a pointer to (or access the value of) a direct
49
  non-static member of an object `obj`, the construction of `obj` shall
50
  have started and its destruction shall not have completed, otherwise the
51
  computation of the pointer value (or accessing the member value) results
52
  in undefined behavior.
53
 
 
 
54
  ``` cpp
55
  struct A { };
56
  struct B : virtual A { };
57
  struct C : B { };
58
  struct D : virtual A { D(A*); };
59
  struct X { X(A*); };
60
 
61
  struct E : C, D, X {
62
- E() : D(this), // undefined: upcast from E* to A*
63
- // might use path E* → D* → A*
64
  // but D is not constructed
65
- // D((C*)this), // defined:
66
- // E* → C* defined because E() has started
67
- // and C* → A* defined because
68
- // C fully constructed
69
- X(this) { // defined: upon construction of X,
70
- // C/B/D/A sublattice is fully constructed
71
- }
72
  };
73
  ```
74
 
 
 
75
  Member functions, including virtual functions ([[class.virtual]]), can
76
  be called during construction or destruction ([[class.base.init]]).
77
  When a virtual function is called directly or indirectly from a
78
  constructor or from a destructor, including during the construction or
79
  destruction of the class’s non-static data members, and the object to
@@ -83,10 +88,12 @@ constructor’s or destructor’s class and not one overriding it in a
83
  more-derived class. If the virtual function call uses an explicit class
84
  member access ([[expr.ref]]) and the object expression refers to the
85
  complete object of `x` or one of that object’s base class subobjects but
86
  not `x` or one of its base class subobjects, the behavior is undefined.
87
 
 
 
88
  ``` cpp
89
  struct V {
90
  virtual void f();
91
  virtual void g();
92
  };
@@ -112,36 +119,39 @@ B::B(V* v, A* a) {
112
  v->g(); // v is base of B, the call is well-defined, calls B::g
113
  a->f(); // undefined behavior, a's type not a base of B
114
  }
115
  ```
116
 
 
 
117
  The `typeid` operator ([[expr.typeid]]) can be used during construction
118
  or destruction ([[class.base.init]]). When `typeid` is used in a
119
- constructor (including the *mem-initializer* or
120
- *brace-or-equal-initializer* for a non-static data member) or in a
121
  destructor, or used in a function called (directly or indirectly) from a
122
  constructor or destructor, if the operand of `typeid` refers to the
123
  object under construction or destruction, `typeid` yields the
124
  `std::type_info` object representing the constructor or destructor’s
125
  class. If the operand of `typeid` refers to the object under
126
  construction or destruction and the static type of the operand is
127
  neither the constructor or destructor’s class nor one of its bases, the
128
- result of `typeid` is undefined.
129
 
130
  `dynamic_cast`s ([[expr.dynamic.cast]]) can be used during construction
131
  or destruction ([[class.base.init]]). When a `dynamic_cast` is used in
132
- a constructor (including the *mem-initializer* or
133
- *brace-or-equal-initializer* for a non-static data member) or in a
134
- destructor, or used in a function called (directly or indirectly) from a
135
- constructor or destructor, if the operand of the `dynamic_cast` refers
136
- to the object under construction or destruction, this object is
137
- considered to be a most derived object that has the type of the
138
- constructor or destructor’s class. If the operand of the `dynamic_cast`
139
- refers to the object under construction or destruction and the static
140
- type of the operand is not a pointer to or object of the constructor or
141
- destructor’s own class or one of its bases, the `dynamic_cast` results
142
- in undefined behavior.
 
143
 
144
  ``` cpp
145
  struct V {
146
  virtual void f();
147
  };
@@ -156,15 +166,14 @@ struct D : A, B {
156
  D() : B((A*)this, this) { }
157
  };
158
 
159
  B::B(V* v, A* a) {
160
  typeid(*this); // type_info for B
161
- typeid(*v); // well-defined: *v has type V, a base of B
162
- // yields type_info for B
163
  typeid(*a); // undefined behavior: type A not a base of B
164
- dynamic_cast<B*>(v); // well-defined: v of type V*, V base of B
165
- // results in B*
166
- dynamic_cast<B*>(a); // undefined behavior,
167
- // a has type A*, A not a base of B
168
  }
169
  ```
170
 
 
 
 
5
  begins execution results in undefined behavior. For an object with a
6
  non-trivial destructor, referring to any non-static member or base class
7
  of the object after the destructor finishes execution results in
8
  undefined behavior.
9
 
10
+ [*Example 1*:
11
+
12
  ``` cpp
13
  struct X { int i; };
14
  struct Y : X { Y(); }; // non-trivial
15
  struct A { int a; };
16
  struct B : public A { int j; Y y; }; // non-trivial
 
39
  Y() : p(&x.j) { // undefined, x is not yet constructed
40
  }
41
  };
42
  ```
43
 
44
+ — *end example*]
45
+
46
  To explicitly or implicitly convert a pointer (a glvalue) referring to
47
  an object of class `X` to a pointer (reference) to a direct or indirect
48
  base class `B` of `X`, the construction of `X` and the construction of
49
  all of its direct or indirect bases that directly or indirectly derive
50
  from `B` shall have started and the destruction of these classes shall
 
53
  non-static member of an object `obj`, the construction of `obj` shall
54
  have started and its destruction shall not have completed, otherwise the
55
  computation of the pointer value (or accessing the member value) results
56
  in undefined behavior.
57
 
58
+ [*Example 2*:
59
+
60
  ``` cpp
61
  struct A { };
62
  struct B : virtual A { };
63
  struct C : B { };
64
  struct D : virtual A { D(A*); };
65
  struct X { X(A*); };
66
 
67
  struct E : C, D, X {
68
+ E() : D(this), // undefined: upcast from E* to A* might use path E* → D* → A*
 
69
  // but D is not constructed
70
+
71
+ // ``D((C*)this)'' would be defined: E* → C* is defined because E() has started,
72
+ // and C* → A* is defined because C is fully constructed
73
+
74
+ X(this) {} // defined: upon construction of X, C/B/D/A sublattice is fully constructed
 
 
75
  };
76
  ```
77
 
78
+ — *end example*]
79
+
80
  Member functions, including virtual functions ([[class.virtual]]), can
81
  be called during construction or destruction ([[class.base.init]]).
82
  When a virtual function is called directly or indirectly from a
83
  constructor or from a destructor, including during the construction or
84
  destruction of the class’s non-static data members, and the object to
 
88
  more-derived class. If the virtual function call uses an explicit class
89
  member access ([[expr.ref]]) and the object expression refers to the
90
  complete object of `x` or one of that object’s base class subobjects but
91
  not `x` or one of its base class subobjects, the behavior is undefined.
92
 
93
+ [*Example 3*:
94
+
95
  ``` cpp
96
  struct V {
97
  virtual void f();
98
  virtual void g();
99
  };
 
119
  v->g(); // v is base of B, the call is well-defined, calls B::g
120
  a->f(); // undefined behavior, a's type not a base of B
121
  }
122
  ```
123
 
124
+ — *end example*]
125
+
126
  The `typeid` operator ([[expr.typeid]]) can be used during construction
127
  or destruction ([[class.base.init]]). When `typeid` is used in a
128
+ constructor (including the *mem-initializer* or default member
129
+ initializer ([[class.mem]]) for a non-static data member) or in a
130
  destructor, or used in a function called (directly or indirectly) from a
131
  constructor or destructor, if the operand of `typeid` refers to the
132
  object under construction or destruction, `typeid` yields the
133
  `std::type_info` object representing the constructor or destructor’s
134
  class. If the operand of `typeid` refers to the object under
135
  construction or destruction and the static type of the operand is
136
  neither the constructor or destructor’s class nor one of its bases, the
137
+ behavior is undefined.
138
 
139
  `dynamic_cast`s ([[expr.dynamic.cast]]) can be used during construction
140
  or destruction ([[class.base.init]]). When a `dynamic_cast` is used in
141
+ a constructor (including the *mem-initializer* or default member
142
+ initializer for a non-static data member) or in a destructor, or used in
143
+ a function called (directly or indirectly) from a constructor or
144
+ destructor, if the operand of the `dynamic_cast` refers to the object
145
+ under construction or destruction, this object is considered to be a
146
+ most derived object that has the type of the constructor or destructor’s
147
+ class. If the operand of the `dynamic_cast` refers to the object under
148
+ construction or destruction and the static type of the operand is not a
149
+ pointer to or object of the constructor or destructor’s own class or one
150
+ of its bases, the `dynamic_cast` results in undefined behavior.
151
+
152
+ [*Example 4*:
153
 
154
  ``` cpp
155
  struct V {
156
  virtual void f();
157
  };
 
166
  D() : B((A*)this, this) { }
167
  };
168
 
169
  B::B(V* v, A* a) {
170
  typeid(*this); // type_info for B
171
+ typeid(*v); // well-defined: *v has type V, a base of B yields type_info for B
 
172
  typeid(*a); // undefined behavior: type A not a base of B
173
+ dynamic_cast<B*>(v); // well-defined: v of type V*, V base of B results in B*
174
+ dynamic_cast<B*>(a); // undefined behavior, a has type A*, A not a base of B
 
 
175
  }
176
  ```
177
 
178
+ — *end example*]
179
+