From Jason Turner

[class.union]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmprcj0tuxg/{from.md → to.md} +145 -45
tmp/tmprcj0tuxg/{from.md → to.md} RENAMED
@@ -1,31 +1,46 @@
1
  ## Unions <a id="class.union">[[class.union]]</a>
2
 
3
- In a union, at most one of the non-static data members can be active at
4
- any time, that is, the value of at most one of the non-static data
5
- members can be stored in a union at any time. One special guarantee is
6
- made in order to simplify the use of unions: If a standard-layout union
7
- contains several standard-layout structs that share a common initial
8
- sequence ([[class.mem]]), and if an object of this standard-layout
9
- union type contains one of the standard-layout structs, it is permitted
10
- to inspect the common initial sequence of any of standard-layout struct
11
- members; see  [[class.mem]]. The size of a union is sufficient to
12
- contain the largest of its non-static data members. Each non-static data
13
- member is allocated as if it were the sole member of a struct. All
14
- non-static data members of a union object have the same address.
 
 
 
 
 
 
 
 
 
 
15
 
16
  A union can have member functions (including constructors and
17
- destructors), but not virtual ([[class.virtual]]) functions. A union
18
- shall not have base classes. A union shall not be used as a base class.
19
- If a union contains a non-static data member of reference type the
20
- program is ill-formed. If any non-static data member of a union has a
21
- non-trivial default constructor ([[class.ctor]]), copy constructor (
22
- [[class.copy]]), move constructor ([[class.copy]]), copy assignment
23
- operator ([[class.copy]]), move assignment operator ([[class.copy]]),
24
- or destructor ([[class.dtor]]), the corresponding member function of
25
- the union must be user-provided or it will be implicitly deleted (
26
- [[dcl.fct.def.delete]]) for the union.
 
 
 
 
 
27
 
28
  Consider the following union:
29
 
30
  ``` cpp
31
  union U {
@@ -39,84 +54,169 @@ Since `std::string` ([[string.classes]]) declares non-trivial versions
39
  of all of the special member functions, `U` will have an implicitly
40
  deleted default constructor, copy/move constructor, copy/move assignment
41
  operator, and destructor. To use `U`, some or all of these member
42
  functions must be user-provided.
43
 
44
- In general, one must use explicit destructor calls and placement new
45
- operators to change the active member of a union. Consider an object `u`
46
- of a `union` type `U` having non-static data members `m` of type `M` and
47
- `n` of type `N`. If `M` has a non-trivial destructor and `N` has a
48
- non-trivial constructor (for instance, if they declare or inherit
49
- virtual functions), the active member of `u` can be safely switched from
50
- `m` to `n` using the destructor and placement new operator as follows:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  ``` cpp
53
  u.m.~M();
54
  new (&u.n) N;
55
  ```
56
 
 
 
 
 
57
  A union of the form
58
 
59
- is called an *anonymous union*; it defines an unnamed object of unnamed
60
- type. The *member-specification* of an anonymous union shall only define
61
- non-static data members. Nested types, anonymous unions, and functions
62
- cannot be declared within an anonymous union. The names of the members
63
- of an anonymous union shall be distinct from the names of any other
64
- entity in the scope in which the anonymous union is declared. For the
65
- purpose of name lookup, after the anonymous union definition, the
66
- members of the anonymous union are considered to have been defined in
67
- the scope in which the anonymous union is declared.
 
 
 
 
 
 
 
68
 
69
  ``` cpp
70
  void f() {
71
  union { int a; const char* p; };
72
  a = 1;
73
  p = "Jennifer";
74
  }
75
  ```
76
 
77
- Here `a` and `p` are used like ordinary (nonmember) variables, but since
78
- they are union members they have the same address.
 
 
79
 
80
  Anonymous unions declared in a named namespace or in the global
81
  namespace shall be declared `static`. Anonymous unions declared at block
82
  scope shall be declared with any storage class allowed for a block-scope
83
  variable, or with no storage class. A storage class is not allowed in a
84
  declaration of an anonymous union in a class scope. An anonymous union
85
  shall not have `private` or `protected` members (Clause 
86
- [[class.access]]). An anonymous union shall not have function members.
87
 
88
  A union for which objects, pointers, or references are declared is not
89
  an anonymous union.
90
 
 
 
91
  ``` cpp
92
  void f() {
93
  union { int aa; char* p; } obj, *ptr = &obj;
94
  aa = 1; // error
95
  ptr->aa = 1; // OK
96
  }
97
  ```
98
 
99
  The assignment to plain `aa` is ill-formed since the member name is not
100
  visible outside the union, and even if it were visible, it is not
101
- associated with any particular object. Initialization of unions with no
102
- user-declared constructors is described in ([[dcl.init.aggr]]).
 
 
 
 
103
 
104
  A *union-like class* is a union or a class that has an anonymous union
105
  as a direct member. A union-like class `X` has a set of *variant
106
  members*. If `X` is a union, a non-static data member of `X` that is not
107
  an anonymous union is a variant member of `X`. In addition, a non-static
108
  data member of an anonymous union that is a member of `X` is also a
109
  variant member of `X`. At most one variant member of a union may have a
110
- *brace-or-equal-initializer*.
 
 
111
 
112
  ``` cpp
113
  union U {
114
  int x = 0;
115
- union { };
 
 
116
  union {
117
  int z;
118
  int y = 1; // error: initialization for second variant member of U
119
  };
120
  };
121
  ```
122
 
 
 
 
1
  ## Unions <a id="class.union">[[class.union]]</a>
2
 
3
+ In a union, a non-static data member is *active* if its name refers to
4
+ an object whose lifetime has begun and has not ended ([[basic.life]]).
5
+ At most one of the non-static data members of an object of union type
6
+ can be active at any time, that is, the value of at most one of the
7
+ non-static data members can be stored in a union at any time.
8
+
9
+ [*Note 1*: One special guarantee is made in order to simplify the use
10
+ of unions: If a standard-layout union contains several standard-layout
11
+ structs that share a common initial sequence ([[class.mem]]), and if a
12
+ non-static data member of an object of this standard-layout union type
13
+ is active and is one of the standard-layout structs, it is permitted to
14
+ inspect the common initial sequence of any of the standard-layout struct
15
+ members; see  [[class.mem]]. — *end note*]
16
+
17
+ The size of a union is sufficient to contain the largest of its
18
+ non-static data members. Each non-static data member is allocated as if
19
+ it were the sole member of a struct.
20
+
21
+ [*Note 2*: A union object and its non-static data members are
22
+ pointer-interconvertible ([[basic.compound]], [[expr.static.cast]]). As
23
+ a consequence, all non-static data members of a union object have the
24
+ same address. — *end note*]
25
 
26
  A union can have member functions (including constructors and
27
+ destructors), but it shall not have virtual ([[class.virtual]])
28
+ functions. A union shall not have base classes. A union shall not be
29
+ used as a base class. If a union contains a non-static data member of
30
+ reference type the program is ill-formed.
31
+
32
+ [*Note 3*: Absent default member initializers ([[class.mem]]), if any
33
+ non-static data member of a union has a non-trivial default
34
+ constructor ([[class.ctor]]), copy constructor ([[class.copy]]), move
35
+ constructor ([[class.copy]]), copy assignment operator (
36
+ [[class.copy]]), move assignment operator ([[class.copy]]), or
37
+ destructor ([[class.dtor]]), the corresponding member function of the
38
+ union must be user-provided or it will be implicitly deleted (
39
+ [[dcl.fct.def.delete]]) for the union. — *end note*]
40
+
41
+ [*Example 1*:
42
 
43
  Consider the following union:
44
 
45
  ``` cpp
46
  union U {
 
54
  of all of the special member functions, `U` will have an implicitly
55
  deleted default constructor, copy/move constructor, copy/move assignment
56
  operator, and destructor. To use `U`, some or all of these member
57
  functions must be user-provided.
58
 
59
+ *end example*]
60
+
61
+ When the left operand of an assignment operator involves a member access
62
+ expression ([[expr.ref]]) that nominates a union member, it may begin
63
+ the lifetime of that union member, as described below. For an expression
64
+ `E`, define the set S(E) of subexpressions of `E` as follows:
65
+
66
+ - If `E` is of the form `A.B`, S(E) contains the elements of S(A), and
67
+ also contains `A.B` if `B` names a union member of a non-class,
68
+ non-array type, or of a class type with a trivial default constructor
69
+ that is not deleted, or an array of such types.
70
+ - If `E` is of the form `A[B]` and is interpreted as a built-in array
71
+ subscripting operator, S(E) is S(A) if `A` is of array type, S(B) if
72
+ `B` is of array type, and empty otherwise.
73
+ - Otherwise, S(E) is empty.
74
+
75
+ In an assignment expression of the form `E1 = E2` that uses either the
76
+ built-in assignment operator ([[expr.ass]]) or a trivial assignment
77
+ operator ([[class.copy]]), for each element `X` of S(`E1`), if
78
+ modification of `X` would have undefined behavior under  [[basic.life]],
79
+ an object of the type of `X` is implicitly created in the nominated
80
+ storage; no initialization is performed and the beginning of its
81
+ lifetime is sequenced after the value computation of the left and right
82
+ operands and before the assignment.
83
+
84
+ [*Note 4*: This ends the lifetime of the previously-active member of
85
+ the union, if any ([[basic.life]]). — *end note*]
86
+
87
+ [*Example 2*:
88
+
89
+ ``` cpp
90
+ union A { int x; int y[4]; };
91
+ struct B { A a; };
92
+ union C { B b; int k; };
93
+ int f() {
94
+ C c; // does not start lifetime of any union member
95
+ c.b.a.y[3] = 4; // OK: S(c.b.a.y[3]) contains c.b and c.b.a.y;
96
+ // creates objects to hold union members c.b and c.b.a.y
97
+ return c.b.a.y[3]; // OK: c.b.a.y refers to newly created object (see [basic.life])
98
+ }
99
+
100
+ struct X { const int a; int b; };
101
+ union Y { X x; int k; };
102
+ void g() {
103
+ Y y = { { 1, 2 } }; // OK, y.x is active union member ([class.mem])
104
+ int n = y.x.a;
105
+ y.k = 4; // OK: ends lifetime of y.x, y.k is active member of union
106
+ y.x.b = n; // undefined behavior: y.x.b modified outside its lifetime,
107
+ // S(y.x.b) is empty because X's default constructor is deleted,
108
+ // so union member y.x's lifetime does not implicitly start
109
+ }
110
+ ```
111
+
112
+ — *end example*]
113
+
114
+ [*Note 5*: In general, one must use explicit destructor calls and
115
+ placement *new-expression* to change the active member of a
116
+ union. — *end note*]
117
+
118
+ [*Example 3*:
119
+
120
+ Consider an object `u` of a `union` type `U` having non-static data
121
+ members `m` of type `M` and `n` of type `N`. If `M` has a non-trivial
122
+ destructor and `N` has a non-trivial constructor (for instance, if they
123
+ declare or inherit virtual functions), the active member of `u` can be
124
+ safely switched from `m` to `n` using the destructor and placement
125
+ *new-expression* as follows:
126
 
127
  ``` cpp
128
  u.m.~M();
129
  new (&u.n) N;
130
  ```
131
 
132
+ — *end example*]
133
+
134
+ ### Anonymous unions <a id="class.union.anon">[[class.union.anon]]</a>
135
+
136
  A union of the form
137
 
138
+ is called an *anonymous union*; it defines an unnamed type and an
139
+ unnamed object of that type called an *anonymous union object*. Each
140
+ *member-declaration* in the *member-specification* of an anonymous union
141
+ shall either define a non-static data member or be a
142
+ *static_assert-declaration*.
143
+
144
+ [*Note 1*: Nested types, anonymous unions, and functions cannot be
145
+ declared within an anonymous union. *end note*]
146
+
147
+ The names of the members of an anonymous union shall be distinct from
148
+ the names of any other entity in the scope in which the anonymous union
149
+ is declared. For the purpose of name lookup, after the anonymous union
150
+ definition, the members of the anonymous union are considered to have
151
+ been defined in the scope in which the anonymous union is declared.
152
+
153
+ [*Example 1*:
154
 
155
  ``` cpp
156
  void f() {
157
  union { int a; const char* p; };
158
  a = 1;
159
  p = "Jennifer";
160
  }
161
  ```
162
 
163
+ Here `a` and `p` are used like ordinary (non-member) variables, but
164
+ since they are union members they have the same address.
165
+
166
+ — *end example*]
167
 
168
  Anonymous unions declared in a named namespace or in the global
169
  namespace shall be declared `static`. Anonymous unions declared at block
170
  scope shall be declared with any storage class allowed for a block-scope
171
  variable, or with no storage class. A storage class is not allowed in a
172
  declaration of an anonymous union in a class scope. An anonymous union
173
  shall not have `private` or `protected` members (Clause 
174
+ [[class.access]]). An anonymous union shall not have member functions.
175
 
176
  A union for which objects, pointers, or references are declared is not
177
  an anonymous union.
178
 
179
+ [*Example 2*:
180
+
181
  ``` cpp
182
  void f() {
183
  union { int aa; char* p; } obj, *ptr = &obj;
184
  aa = 1; // error
185
  ptr->aa = 1; // OK
186
  }
187
  ```
188
 
189
  The assignment to plain `aa` is ill-formed since the member name is not
190
  visible outside the union, and even if it were visible, it is not
191
+ associated with any particular object.
192
+
193
+ — *end example*]
194
+
195
+ [*Note 2*: Initialization of unions with no user-declared constructors
196
+ is described in  [[dcl.init.aggr]]. — *end note*]
197
 
198
  A *union-like class* is a union or a class that has an anonymous union
199
  as a direct member. A union-like class `X` has a set of *variant
200
  members*. If `X` is a union, a non-static data member of `X` that is not
201
  an anonymous union is a variant member of `X`. In addition, a non-static
202
  data member of an anonymous union that is a member of `X` is also a
203
  variant member of `X`. At most one variant member of a union may have a
204
+ default member initializer.
205
+
206
+ [*Example 3*:
207
 
208
  ``` cpp
209
  union U {
210
  int x = 0;
211
+ union {
212
+ int k;
213
+ };
214
  union {
215
  int z;
216
  int y = 1; // error: initialization for second variant member of U
217
  };
218
  };
219
  ```
220
 
221
+ — *end example*]
222
+