From Jason Turner

[class.union]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpmifl3opo/{from.md → to.md} +34 -28
tmp/tmpmifl3opo/{from.md → to.md} RENAMED
@@ -1,7 +1,9 @@
1
  ## Unions <a id="class.union">[[class.union]]</a>
2
 
 
 
3
  A *union* is a class defined with the *class-key* `union`.
4
 
5
  In a union, a non-static data member is *active* if its name refers to
6
  an object whose lifetime has begun and has not ended [[basic.life]]. At
7
  most one of the non-static data members of an object of union type can
@@ -19,27 +21,29 @@ members; see  [[class.mem]]. — *end note*]
19
  The size of a union is sufficient to contain the largest of its
20
  non-static data members. Each non-static data member is allocated as if
21
  it were the sole member of a non-union class.
22
 
23
  [*Note 2*: A union object and its non-static data members are
24
- pointer-interconvertible ([[basic.compound]], [[expr.static.cast]]). As
25
- a consequence, all non-static data members of a union object have the
26
- same address. — *end note*]
27
 
28
  A union can have member functions (including constructors and
29
  destructors), but it shall not have virtual [[class.virtual]] functions.
30
  A union shall not have base classes. A union shall not be used as a base
31
  class. If a union contains a non-static data member of reference type
32
  the program is ill-formed.
33
 
34
- [*Note 3*: Absent default member initializers [[class.mem]], if any
35
- non-static data member of a union has a non-trivial default constructor
 
 
36
  [[class.default.ctor]], copy constructor, move constructor
37
  [[class.copy.ctor]], copy assignment operator, move assignment operator
38
  [[class.copy.assign]], or destructor [[class.dtor]], the corresponding
39
  member function of the union must be user-provided or it will be
40
- implicitly deleted [[dcl.fct.def.delete]] for the union. — *end note*]
41
 
42
  [*Example 1*:
43
 
44
  Consider the following union:
45
 
@@ -57,10 +61,12 @@ default constructor, copy/move constructor, copy/move assignment
57
  operator, and destructor. To use `U`, some or all of these member
58
  functions must be user-provided.
59
 
60
  — *end example*]
61
 
 
 
62
  When the left operand of an assignment operator involves a member access
63
  expression [[expr.ref]] that nominates a union member, it may begin the
64
  lifetime of that union member, as described below. For an expression
65
  `E`, define the set S(E) of subexpressions of `E` as follows:
66
 
@@ -91,32 +97,32 @@ the union, if any [[basic.life]]. — *end note*]
91
  union A { int x; int y[4]; };
92
  struct B { A a; };
93
  union C { B b; int k; };
94
  int f() {
95
  C c; // does not start lifetime of any union member
96
- c.b.a.y[3] = 4; // OK: S(c.b.a.y[3]) contains c.b and c.b.a.y;
97
  // creates objects to hold union members c.b and c.b.a.y
98
- return c.b.a.y[3]; // OK: c.b.a.y refers to newly created object (see [basic.life])
99
  }
100
 
101
  struct X { const int a; int b; };
102
  union Y { X x; int k; };
103
  void g() {
104
  Y y = { { 1, 2 } }; // OK, y.x is active union member[class.mem]
105
  int n = y.x.a;
106
- y.k = 4; // OK: ends lifetime of y.x, y.k is active member of union
107
  y.x.b = n; // undefined behavior: y.x.b modified outside its lifetime,
108
  // S(y.x.b) is empty because X's default constructor is deleted,
109
  // so union member y.x's lifetime does not implicitly start
110
  }
111
  ```
112
 
113
  — *end example*]
114
 
115
- [*Note 5*: In general, one must use explicit destructor calls and
116
- placement *new-expression* to change the active member of a
117
- union. — *end note*]
118
 
119
  [*Example 3*:
120
 
121
  Consider an object `u` of a `union` type `U` having non-static data
122
  members `m` of type `M` and `n` of type `N`. If `M` has a non-trivial
@@ -139,20 +145,18 @@ A union of the form
139
  ``` bnf
140
  union '{' member-specification '}' ';'
141
  ```
142
 
143
  is called an *anonymous union*; it defines an unnamed type and an
144
- unnamed object of that type called an *anonymous union object*. Each
145
- *member-declaration* in the *member-specification* of an anonymous union
146
- shall either define a non-static data member or be a
147
- *static_assert-declaration*. Nested types, anonymous unions, and
 
148
  functions shall not be declared within an anonymous union. The names of
149
- the members of an anonymous union shall be distinct from the names of
150
- any other entity in the scope in which the anonymous union is declared.
151
- For the purpose of name lookup, after the anonymous union definition,
152
- the members of the anonymous union are considered to have been defined
153
- in the scope in which the anonymous union is declared.
154
 
155
  [*Example 1*:
156
 
157
  ``` cpp
158
  void f() {
@@ -165,17 +169,17 @@ void f() {
165
  Here `a` and `p` are used like ordinary (non-member) variables, but
166
  since they are union members they have the same address.
167
 
168
  — *end example*]
169
 
170
- Anonymous unions declared in a named namespace or in the global
171
- namespace shall be declared `static`. Anonymous unions declared at block
172
- scope shall be declared with any storage class allowed for a block-scope
173
  variable, or with no storage class. A storage class is not allowed in a
174
- declaration of an anonymous union in a class scope. An anonymous union
175
- shall not have private or protected members [[class.access]]. An
176
- anonymous union shall not have member functions.
177
 
178
  A union for which objects, pointers, or references are declared is not
179
  an anonymous union.
180
 
181
  [*Example 2*:
@@ -192,11 +196,13 @@ The assignment to plain `aa` is ill-formed since the member name is not
192
  visible outside the union, and even if it were visible, it is not
193
  associated with any particular object.
194
 
195
  — *end example*]
196
 
197
- [*Note 1*: Initialization of unions with no user-declared constructors
 
 
198
  is described in  [[dcl.init.aggr]]. — *end note*]
199
 
200
  A *union-like class* is a union or a class that has an anonymous union
201
  as a direct member. A union-like class `X` has a set of *variant
202
  members*. If `X` is a union, a non-static data member of `X` that is not
 
1
  ## Unions <a id="class.union">[[class.union]]</a>
2
 
3
+ ### General <a id="class.union.general">[[class.union.general]]</a>
4
+
5
  A *union* is a class defined with the *class-key* `union`.
6
 
7
  In a union, a non-static data member is *active* if its name refers to
8
  an object whose lifetime has begun and has not ended [[basic.life]]. At
9
  most one of the non-static data members of an object of union type can
 
21
  The size of a union is sufficient to contain the largest of its
22
  non-static data members. Each non-static data member is allocated as if
23
  it were the sole member of a non-union class.
24
 
25
  [*Note 2*: A union object and its non-static data members are
26
+ pointer-interconvertible [[basic.compound]], [[expr.static.cast]]. As a
27
+ consequence, all non-static data members of a union object have the same
28
+ address. — *end note*]
29
 
30
  A union can have member functions (including constructors and
31
  destructors), but it shall not have virtual [[class.virtual]] functions.
32
  A union shall not have base classes. A union shall not be used as a base
33
  class. If a union contains a non-static data member of reference type
34
  the program is ill-formed.
35
 
36
+ [*Note 3*:
37
+
38
+ Absent default member initializers [[class.mem]], if any non-static data
39
+ member of a union has a non-trivial default constructor
40
  [[class.default.ctor]], copy constructor, move constructor
41
  [[class.copy.ctor]], copy assignment operator, move assignment operator
42
  [[class.copy.assign]], or destructor [[class.dtor]], the corresponding
43
  member function of the union must be user-provided or it will be
44
+ implicitly deleted [[dcl.fct.def.delete]] for the union.
45
 
46
  [*Example 1*:
47
 
48
  Consider the following union:
49
 
 
61
  operator, and destructor. To use `U`, some or all of these member
62
  functions must be user-provided.
63
 
64
  — *end example*]
65
 
66
+ — *end note*]
67
+
68
  When the left operand of an assignment operator involves a member access
69
  expression [[expr.ref]] that nominates a union member, it may begin the
70
  lifetime of that union member, as described below. For an expression
71
  `E`, define the set S(E) of subexpressions of `E` as follows:
72
 
 
97
  union A { int x; int y[4]; };
98
  struct B { A a; };
99
  union C { B b; int k; };
100
  int f() {
101
  C c; // does not start lifetime of any union member
102
+ c.b.a.y[3] = 4; // OK, S(c.b.a.y[3]) contains c.b and c.b.a.y;
103
  // creates objects to hold union members c.b and c.b.a.y
104
+ return c.b.a.y[3]; // OK, c.b.a.y refers to newly created object (see [basic.life])
105
  }
106
 
107
  struct X { const int a; int b; };
108
  union Y { X x; int k; };
109
  void g() {
110
  Y y = { { 1, 2 } }; // OK, y.x is active union member[class.mem]
111
  int n = y.x.a;
112
+ y.k = 4; // OK, ends lifetime of y.x, y.k is active member of union
113
  y.x.b = n; // undefined behavior: y.x.b modified outside its lifetime,
114
  // S(y.x.b) is empty because X's default constructor is deleted,
115
  // so union member y.x's lifetime does not implicitly start
116
  }
117
  ```
118
 
119
  — *end example*]
120
 
121
+ [*Note 5*: In cases where the above rule does not apply, the active
122
+ member of a union can only be changed by the use of a placement
123
+ *new-expression*. — *end note*]
124
 
125
  [*Example 3*:
126
 
127
  Consider an object `u` of a `union` type `U` having non-static data
128
  members `m` of type `M` and `n` of type `N`. If `M` has a non-trivial
 
145
  ``` bnf
146
  union '{' member-specification '}' ';'
147
  ```
148
 
149
  is called an *anonymous union*; it defines an unnamed type and an
150
+ unnamed object of that type called an *anonymous union member* if it is
151
+ a non-static data member or an *anonymous union variable* otherwise.
152
+ Each *member-declaration* in the *member-specification* of an anonymous
153
+ union shall either define one or more public non-static data members or
154
+ be a *static_assert-declaration*. Nested types, anonymous unions, and
155
  functions shall not be declared within an anonymous union. The names of
156
+ the members of an anonymous union are bound in the scope inhabited by
157
+ the union declaration.
 
 
 
158
 
159
  [*Example 1*:
160
 
161
  ``` cpp
162
  void f() {
 
169
  Here `a` and `p` are used like ordinary (non-member) variables, but
170
  since they are union members they have the same address.
171
 
172
  — *end example*]
173
 
174
+ Anonymous unions declared in the scope of a namespace with external
175
+ linkage shall be declared `static`. Anonymous unions declared at block
176
+ scope shall be declared with any storage class allowed for a block
177
  variable, or with no storage class. A storage class is not allowed in a
178
+ declaration of an anonymous union in a class scope.
179
+
180
+ [*Note 1*:
181
 
182
  A union for which objects, pointers, or references are declared is not
183
  an anonymous union.
184
 
185
  [*Example 2*:
 
196
  visible outside the union, and even if it were visible, it is not
197
  associated with any particular object.
198
 
199
  — *end example*]
200
 
201
+ *end note*]
202
+
203
+ [*Note 2*: Initialization of unions with no user-declared constructors
204
  is described in  [[dcl.init.aggr]]. — *end note*]
205
 
206
  A *union-like class* is a union or a class that has an anonymous union
207
  as a direct member. A union-like class `X` has a set of *variant
208
  members*. If `X` is a union, a non-static data member of `X` that is not