From Jason Turner

[expr.static.cast]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp5zuyfws4/{from.md → to.md} +84 -74
tmp/tmp5zuyfws4/{from.md → to.md} RENAMED
@@ -1,21 +1,21 @@
1
- ### Static cast <a id="expr.static.cast">[[expr.static.cast]]</a>
2
 
3
  The result of the expression `static_cast<T>(v)` is the result of
4
  converting the expression `v` to type `T`. If `T` is an lvalue reference
5
  type or an rvalue reference to function type, the result is an lvalue;
6
  if `T` is an rvalue reference to object type, the result is an xvalue;
7
  otherwise, the result is a prvalue. The `static_cast` operator shall not
8
- cast away constness ([[expr.const.cast]]).
9
 
10
  An lvalue of type “*cv1* `B`”, where `B` is a class type, can be cast to
11
- type “reference to *cv2* `D`”, where `D` is a class derived (Clause 
12
- [[class.derived]]) from `B`, if *cv2* is the same cv-qualification as,
13
- or greater cv-qualification than, *cv1*. If `B` is a virtual base class
14
- of `D` or a base class of a virtual base class of `D`, or if no valid
15
- standard conversion from “pointer to `D`” to “pointer to `B`” exists (
16
- [[conv.ptr]]), the program is ill-formed. An xvalue of type “*cv1* `B`”
17
  can be cast to type “rvalue reference to *cv2* `D`” with the same
18
  constraints as for an lvalue of type “*cv1* `B`”. If the object of type
19
  “*cv1* `B`” is actually a base class subobject of an object of type `D`,
20
  the result refers to the enclosing object of type `D`. Otherwise, the
21
  behavior is undefined.
@@ -26,65 +26,70 @@ behavior is undefined.
26
  struct B { };
27
  struct D : public B { };
28
  D d;
29
  B &br = d;
30
 
31
- static_cast<D&>(br); // produces lvalue to the original d object
32
  ```
33
 
34
  — *end example*]
35
 
36
  An lvalue of type “*cv1* `T1`” can be cast to type “rvalue reference to
37
- *cv2* `T2`” if “*cv2* `T2`” is reference-compatible with “*cv1* `T1`” (
38
- [[dcl.init.ref]]). If the value is not a bit-field, the result refers to
39
  the object or the specified base class subobject thereof; otherwise, the
40
- lvalue-to-rvalue conversion ([[conv.lval]]) is applied to the bit-field
41
  and the resulting prvalue is used as the *expression* of the
42
- `static_cast` for the remainder of this section. If `T2` is an
43
- inaccessible (Clause  [[class.access]]) or ambiguous (
44
- [[class.member.lookup]]) base class of `T1`, a program that necessitates
45
- such a cast is ill-formed.
46
 
47
- An expression `e` can be explicitly converted to a type `T` if there is
48
- an implicit conversion sequence ([[over.best.ics]]) from `e` to `T`, or
49
- if overload resolution for a direct-initialization ([[dcl.init]]) of an
50
- object or reference of type `T` from `e` would find at least one viable
51
- function ([[over.match.viable]]). If `T` is a reference type, the
52
- effect is the same as performing the declaration and initialization
 
 
 
53
 
54
  ``` cpp
55
- T t(e);
56
  ```
57
 
58
- for some invented temporary variable `t` ([[dcl.init]]) and then using
59
- the temporary variable as the result of the conversion. Otherwise, the
60
- result object is direct-initialized from `e`.
61
 
62
  [*Note 1*: The conversion is ill-formed when attempting to convert an
63
  expression of class type to an inaccessible or ambiguous base
64
  class. — *end note*]
65
 
 
 
 
 
66
  Otherwise, the `static_cast` shall perform one of the conversions listed
67
  below. No other conversion shall be performed explicitly using a
68
  `static_cast`.
69
 
70
  Any expression can be explicitly converted to type cv `void`, in which
71
- case it becomes a discarded-value expression (Clause  [[expr]]).
72
 
73
- [*Note 2*: However, if the value is in a temporary object (
74
- [[class.temporary]]), the destructor for that object is not executed
75
  until the usual time, and the value of the object is preserved for the
76
  purpose of executing the destructor. — *end note*]
77
 
78
- The inverse of any standard conversion sequence (Clause  [[conv]]) not
79
- containing an lvalue-to-rvalue ([[conv.lval]]), array-to-pointer (
80
- [[conv.array]]), function-to-pointer ([[conv.func]]), null pointer (
81
- [[conv.ptr]]), null member pointer ([[conv.mem]]), boolean (
82
- [[conv.bool]]), or function pointer ([[conv.fctptr]]) conversion, can
83
- be performed explicitly using `static_cast`. A program is ill-formed if
84
- it uses `static_cast` to perform the inverse of an ill-formed standard
85
- conversion sequence.
86
 
87
  [*Example 2*:
88
 
89
  ``` cpp
90
  struct B { };
@@ -95,63 +100,68 @@ void f() {
95
  }
96
  ```
97
 
98
  — *end example*]
99
 
100
- The lvalue-to-rvalue ([[conv.lval]]), array-to-pointer (
101
- [[conv.array]]), and function-to-pointer ([[conv.func]]) conversions
102
- are applied to the operand. Such a `static_cast` is subject to the
103
- restriction that the explicit conversion does not cast away constness (
104
- [[expr.const.cast]]), and the following additional rules for specific
105
- cases:
106
 
107
- A value of a scoped enumeration type ([[dcl.enum]]) can be explicitly
108
- converted to an integral type. When that type is cv `bool`, the
109
- resulting value is `false` if the original value is zero and `true` for
110
- all other values. For the remaining integral types, the value is
111
- unchanged if the original value can be represented by the specified
112
- type. Otherwise, the resulting value is unspecified. A value of a scoped
113
- enumeration type can also be explicitly converted to a floating-point
114
- type; the result is the same as that of converting from the original
115
- value to the floating-point type.
116
 
117
  A value of integral or enumeration type can be explicitly converted to a
118
- complete enumeration type. The value is unchanged if the original value
119
- is within the range of the enumeration values ([[dcl.enum]]).
120
- Otherwise, the behavior is undefined. A value of floating-point type can
121
- also be explicitly converted to an enumeration type. The resulting value
122
- is the same as converting the original value to the underlying type of
123
- the enumeration ([[conv.fpint]]), and subsequently to the enumeration
124
- type.
 
 
 
125
 
126
  A prvalue of type “pointer to *cv1* `B`”, where `B` is a class type, can
127
  be converted to a prvalue of type “pointer to *cv2* `D`”, where `D` is a
128
- class derived (Clause  [[class.derived]]) from `B`, if *cv2* is the same
129
  cv-qualification as, or greater cv-qualification than, *cv1*. If `B` is
130
  a virtual base class of `D` or a base class of a virtual base class of
131
  `D`, or if no valid standard conversion from “pointer to `D`” to
132
- “pointer to `B`” exists ([[conv.ptr]]), the program is ill-formed. The
133
- null pointer value ([[conv.ptr]]) is converted to the null pointer
134
  value of the destination type. If the prvalue of type “pointer to *cv1*
135
  `B`” points to a `B` that is actually a subobject of an object of type
136
  `D`, the resulting pointer points to the enclosing object of type `D`.
137
  Otherwise, the behavior is undefined.
138
 
139
  A prvalue of type “pointer to member of `D` of type *cv1* `T`” can be
140
  converted to a prvalue of type “pointer to member of `B` of type *cv2*
141
- `T`”, where `B` is a base class (Clause  [[class.derived]]) of `D`, if
142
- *cv2* is the same cv-qualification as, or greater cv-qualification than,
143
- *cv1*.[^11] If no valid standard conversion from “pointer to member of
144
- `B` of type `T`” to “pointer to member of `D` of type `T`” exists (
145
- [[conv.mem]]), the program is ill-formed. The null member pointer
146
- value ([[conv.mem]]) is converted to the null member pointer value of
147
- the destination type. If class `B` contains the original member, or is a
148
- base or derived class of the class containing the original member, the
149
- resulting pointer to member points to the original member. Otherwise,
150
- the behavior is undefined.
151
 
152
- [*Note 3*: Although class `B` need not contain the original member, the
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  dynamic type of the object with which indirection through the pointer to
154
  member is performed must contain the original member; see 
155
  [[expr.mptr.oper]]. — *end note*]
156
 
157
  A prvalue of type “pointer to *cv1* `void`” can be converted to a
@@ -160,11 +170,11 @@ prvalue of type “pointer to *cv2* `T`”, where `T` is an object type and
160
  *cv1*. If the original pointer value represents the address `A` of a
161
  byte in memory and `A` does not satisfy the alignment requirement of
162
  `T`, then the resulting pointer value is unspecified. Otherwise, if the
163
  original pointer value points to an object *a*, and there is an object
164
  *b* of type `T` (ignoring cv-qualification) that is
165
- pointer-interconvertible ([[basic.compound]]) with *a*, the result is a
166
  pointer to *b*. Otherwise, the pointer value is unchanged by the
167
  conversion.
168
 
169
  [*Example 3*:
170
 
 
1
+ #### Static cast <a id="expr.static.cast">[[expr.static.cast]]</a>
2
 
3
  The result of the expression `static_cast<T>(v)` is the result of
4
  converting the expression `v` to type `T`. If `T` is an lvalue reference
5
  type or an rvalue reference to function type, the result is an lvalue;
6
  if `T` is an rvalue reference to object type, the result is an xvalue;
7
  otherwise, the result is a prvalue. The `static_cast` operator shall not
8
+ cast away constness [[expr.const.cast]].
9
 
10
  An lvalue of type “*cv1* `B`”, where `B` is a class type, can be cast to
11
+ type “reference to *cv2* `D`”, where `D` is a class derived
12
+ [[class.derived]] from `B`, if *cv2* is the same cv-qualification as, or
13
+ greater cv-qualification than, *cv1*. If `B` is a virtual base class of
14
+ `D` or a base class of a virtual base class of `D`, or if no valid
15
+ standard conversion from “pointer to `D`” to “pointer to `B`” exists
16
+ [[conv.ptr]], the program is ill-formed. An xvalue of type “*cv1* `B`”
17
  can be cast to type “rvalue reference to *cv2* `D`” with the same
18
  constraints as for an lvalue of type “*cv1* `B`”. If the object of type
19
  “*cv1* `B`” is actually a base class subobject of an object of type `D`,
20
  the result refers to the enclosing object of type `D`. Otherwise, the
21
  behavior is undefined.
 
26
  struct B { };
27
  struct D : public B { };
28
  D d;
29
  B &br = d;
30
 
31
+ static_cast<D&>(br); // produces lvalue denoting the original d object
32
  ```
33
 
34
  — *end example*]
35
 
36
  An lvalue of type “*cv1* `T1`” can be cast to type “rvalue reference to
37
+ *cv2* `T2`” if “*cv2* `T2`” is reference-compatible with “*cv1* `T1`”
38
+ [[dcl.init.ref]]. If the value is not a bit-field, the result refers to
39
  the object or the specified base class subobject thereof; otherwise, the
40
+ lvalue-to-rvalue conversion [[conv.lval]] is applied to the bit-field
41
  and the resulting prvalue is used as the *expression* of the
42
+ `static_cast` for the remainder of this subclause. If `T2` is an
43
+ inaccessible [[class.access]] or ambiguous [[class.member.lookup]] base
44
+ class of `T1`, a program that necessitates such a cast is ill-formed.
 
45
 
46
+ An expression E can be explicitly converted to a type `T` if there is an
47
+ implicit conversion sequence [[over.best.ics]] from E to `T`, if
48
+ overload resolution for a direct-initialization [[dcl.init]] of an
49
+ object or reference of type `T` from E would find at least one viable
50
+ function [[over.match.viable]], or if `T` is an aggregate type
51
+ [[dcl.init.aggr]] having a first element `x` and there is an implicit
52
+ conversion sequence from E to the type of `x`. If `T` is a reference
53
+ type, the effect is the same as performing the declaration and
54
+ initialization
55
 
56
  ``` cpp
57
+ T t(E);
58
  ```
59
 
60
+ for some invented temporary variable `t` [[dcl.init]] and then using the
61
+ temporary variable as the result of the conversion. Otherwise, the
62
+ result object is direct-initialized from E.
63
 
64
  [*Note 1*: The conversion is ill-formed when attempting to convert an
65
  expression of class type to an inaccessible or ambiguous base
66
  class. — *end note*]
67
 
68
+ [*Note 2*: If `T` is “array of unknown bound of `U`”, this
69
+ direct-initialization defines the type of the expression as
70
+ `U[1]`. — *end note*]
71
+
72
  Otherwise, the `static_cast` shall perform one of the conversions listed
73
  below. No other conversion shall be performed explicitly using a
74
  `static_cast`.
75
 
76
  Any expression can be explicitly converted to type cv `void`, in which
77
+ case it becomes a discarded-value expression [[expr.prop]].
78
 
79
+ [*Note 3*: However, if the value is in a temporary object
80
+ [[class.temporary]], the destructor for that object is not executed
81
  until the usual time, and the value of the object is preserved for the
82
  purpose of executing the destructor. — *end note*]
83
 
84
+ The inverse of any standard conversion sequence [[conv]] not containing
85
+ an lvalue-to-rvalue [[conv.lval]], array-to-pointer [[conv.array]],
86
+ function-to-pointer [[conv.func]], null pointer [[conv.ptr]], null
87
+ member pointer [[conv.mem]], boolean [[conv.bool]], or function pointer
88
+ [[conv.fctptr]] conversion, can be performed explicitly using
89
+ `static_cast`. A program is ill-formed if it uses `static_cast` to
90
+ perform the inverse of an ill-formed standard conversion sequence.
 
91
 
92
  [*Example 2*:
93
 
94
  ``` cpp
95
  struct B { };
 
100
  }
101
  ```
102
 
103
  — *end example*]
104
 
105
+ The lvalue-to-rvalue [[conv.lval]], array-to-pointer [[conv.array]], and
106
+ function-to-pointer [[conv.func]] conversions are applied to the
107
+ operand. Such a `static_cast` is subject to the restriction that the
108
+ explicit conversion does not cast away constness [[expr.const.cast]],
109
+ and the following additional rules for specific cases:
 
110
 
111
+ A value of a scoped enumeration type [[dcl.enum]] can be explicitly
112
+ converted to an integral type; the result is the same as that of
113
+ converting to the enumeration’s underlying type and then to the
114
+ destination type. A value of a scoped enumeration type can also be
115
+ explicitly converted to a floating-point type; the result is the same as
116
+ that of converting from the original value to the floating-point type.
 
 
 
117
 
118
  A value of integral or enumeration type can be explicitly converted to a
119
+ complete enumeration type. If the enumeration type has a fixed
120
+ underlying type, the value is first converted to that type by integral
121
+ conversion, if necessary, and then to the enumeration type. If the
122
+ enumeration type does not have a fixed underlying type, the value is
123
+ unchanged if the original value is within the range of the enumeration
124
+ values [[dcl.enum]], and otherwise, the behavior is undefined. A value
125
+ of floating-point type can also be explicitly converted to an
126
+ enumeration type. The resulting value is the same as converting the
127
+ original value to the underlying type of the enumeration [[conv.fpint]],
128
+ and subsequently to the enumeration type.
129
 
130
  A prvalue of type “pointer to *cv1* `B`”, where `B` is a class type, can
131
  be converted to a prvalue of type “pointer to *cv2* `D`”, where `D` is a
132
+ complete class derived [[class.derived]] from `B`, if *cv2* is the same
133
  cv-qualification as, or greater cv-qualification than, *cv1*. If `B` is
134
  a virtual base class of `D` or a base class of a virtual base class of
135
  `D`, or if no valid standard conversion from “pointer to `D`” to
136
+ “pointer to `B`” exists [[conv.ptr]], the program is ill-formed. The
137
+ null pointer value [[basic.compound]] is converted to the null pointer
138
  value of the destination type. If the prvalue of type “pointer to *cv1*
139
  `B`” points to a `B` that is actually a subobject of an object of type
140
  `D`, the resulting pointer points to the enclosing object of type `D`.
141
  Otherwise, the behavior is undefined.
142
 
143
  A prvalue of type “pointer to member of `D` of type *cv1* `T`” can be
144
  converted to a prvalue of type “pointer to member of `B` of type *cv2*
145
+ `T`”, where `D` is a complete class type and `B` is a base class
146
+ [[class.derived]] of `D`, if *cv2* is the same cv-qualification as, or
147
+ greater cv-qualification than, *cv1*.
 
 
 
 
 
 
 
148
 
149
+ [*Note 4*: Function types (including those used in
150
+ pointer-to-member-function types) are never cv-qualified
151
+ [[dcl.fct]]. — *end note*]
152
+
153
+ If no valid standard conversion from “pointer to member of `B` of type
154
+ `T`” to “pointer to member of `D` of type `T`” exists [[conv.mem]], the
155
+ program is ill-formed. The null member pointer value [[conv.mem]] is
156
+ converted to the null member pointer value of the destination type. If
157
+ class `B` contains the original member, or is a base or derived class of
158
+ the class containing the original member, the resulting pointer to
159
+ member points to the original member. Otherwise, the behavior is
160
+ undefined.
161
+
162
+ [*Note 5*: Although class `B` need not contain the original member, the
163
  dynamic type of the object with which indirection through the pointer to
164
  member is performed must contain the original member; see 
165
  [[expr.mptr.oper]]. — *end note*]
166
 
167
  A prvalue of type “pointer to *cv1* `void`” can be converted to a
 
170
  *cv1*. If the original pointer value represents the address `A` of a
171
  byte in memory and `A` does not satisfy the alignment requirement of
172
  `T`, then the resulting pointer value is unspecified. Otherwise, if the
173
  original pointer value points to an object *a*, and there is an object
174
  *b* of type `T` (ignoring cv-qualification) that is
175
+ pointer-interconvertible [[basic.compound]] with *a*, the result is a
176
  pointer to *b*. Otherwise, the pointer value is unchanged by the
177
  conversion.
178
 
179
  [*Example 3*:
180