From Jason Turner

[class.union]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp52x3luf4/{from.md → to.md} +41 -39
tmp/tmp52x3luf4/{from.md → to.md} RENAMED
@@ -1,44 +1,45 @@
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
 
@@ -48,21 +49,21 @@ union U {
48
  float f;
49
  std::string s;
50
  };
51
  ```
52
 
53
- Since `std::string` ([[string.classes]]) declares non-trivial versions
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
@@ -71,20 +72,20 @@ the lifetime of that union member, as described below. For an expression
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]; };
@@ -98,11 +99,11 @@ int f() {
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
@@ -133,24 +134,25 @@ new (&u.n) N;
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() {
@@ -168,12 +170,12 @@ since they are union members they have the same address.
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*:
@@ -190,11 +192,11 @@ 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
 
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
8
+ be active at any time, that is, the value of at most one of the
9
  non-static data members can be stored in a union at any time.
10
 
11
  [*Note 1*: One special guarantee is made in order to simplify the use
12
  of unions: If a standard-layout union contains several standard-layout
13
+ structs that share a common initial sequence [[class.mem]], and if a
14
  non-static data member of an object of this standard-layout union type
15
  is active and is one of the standard-layout structs, it is permitted to
16
  inspect the common initial sequence of any of the standard-layout struct
17
  members; see  [[class.mem]]. — *end note*]
18
 
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
 
 
49
  float f;
50
  std::string s;
51
  };
52
  ```
53
 
54
+ Since `std::string` [[string.classes]] declares non-trivial versions of
55
+ all of the special member functions, `U` will have an implicitly deleted
56
+ 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
 
67
  - If `E` is of the form `A.B`, S(E) contains the elements of S(A), and
68
  also contains `A.B` if `B` names a union member of a non-class,
69
  non-array type, or of a class type with a trivial default constructor
 
72
  subscripting operator, S(E) is S(A) if `A` is of array type, S(B) if
73
  `B` is of array type, and empty otherwise.
74
  - Otherwise, S(E) is empty.
75
 
76
  In an assignment expression of the form `E1 = E2` that uses either the
77
+ built-in assignment operator [[expr.ass]] or a trivial assignment
78
+ operator [[class.copy.assign]], for each element `X` of S(`E1`), if
79
  modification of `X` would have undefined behavior under  [[basic.life]],
80
  an object of the type of `X` is implicitly created in the nominated
81
  storage; no initialization is performed and the beginning of its
82
  lifetime is sequenced after the value computation of the left and right
83
  operands and before the assignment.
84
 
85
  [*Note 4*: This ends the lifetime of the previously-active member of
86
+ the union, if any [[basic.life]]. — *end note*]
87
 
88
  [*Example 2*:
89
 
90
  ``` cpp
91
  union A { int x; int y[4]; };
 
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
 
134
 
135
  ### Anonymous unions <a id="class.union.anon">[[class.union.anon]]</a>
136
 
137
  A union of the form
138
 
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() {
 
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
  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