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
|
| 25 |
-
|
| 26 |
-
|
| 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*:
|
| 35 |
-
|
|
|
|
|
|
|
| 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.
|
| 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
|
| 97 |
// creates objects to hold union members c.b and c.b.a.y
|
| 98 |
-
return c.b.a.y[3]; // OK
|
| 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
|
| 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
|
| 116 |
-
|
| 117 |
-
|
| 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
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
|
|
|
| 148 |
functions shall not be declared within an anonymous union. The names of
|
| 149 |
-
the members of an anonymous union
|
| 150 |
-
|
| 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
|
| 171 |
-
|
| 172 |
-
scope shall be declared with any storage class allowed for a block
|
| 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.
|
| 175 |
-
|
| 176 |
-
|
| 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 |
-
|
|
|
|
|
|
|
| 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
|