From Jason Turner

[expr.static.cast]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpj_1fm31m/{from.md → to.md} +109 -82
tmp/tmpj_1fm31m/{from.md → to.md} RENAMED
@@ -5,80 +5,100 @@ 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 a valid standard conversion from
13
- “pointer to `D`” to “pointer to `B` exists ([[conv.ptr]]), *cv2* is
14
- the same cv-qualification as, or greater cv-qualification than, *cv1*,
15
- and `B` is neither a virtual base class of `D` nor a base class of a
16
- virtual base class of `D`. The result has type “*cv2* `D`. An xvalue of
17
- type “*cv1* `B`” may be cast to type “rvalue reference to *cv2* `D`”
18
- with the same constraints as for an lvalue of type “*cv1* `B`.” If the
19
- object of type “*cv1* `B`” is actually a subobject of an object of type
20
- `D`, the result refers to the enclosing object of type `D`. Otherwise,
21
- the behavior is undefined.
 
 
22
 
23
  ``` cpp
24
  struct B { };
25
  struct D : public B { };
26
  D d;
27
  B &br = d;
28
 
29
  static_cast<D&>(br); // produces lvalue to the original d object
30
  ```
31
 
32
- A glvalue, class prvalue, or array prvalue of type “*cv1* `T1`” can be
33
- cast to type “rvalue reference to *cv2* `T2`” if “*cv2* `T2`” is
34
- reference-compatible with “*cv1* `T1`” ([[dcl.init.ref]]). If the value
35
- is not a bit-field, the result refers to the object or the specified
36
- base class subobject thereof; otherwise, the lvalue-to-rvalue
37
- conversion ([[conv.lval]]) is applied to the bit-field and the
38
- resulting prvalue is used as the *expression* of the `static_cast` for
39
- the remainder of this section. If `T2` is an inaccessible (Clause 
40
- [[class.access]]) or ambiguous ([[class.member.lookup]]) base class of
41
- `T1`, a program that necessitates such a cast is ill-formed.
42
 
43
- An expression `e` can be explicitly converted to a type `T` using a
44
- `static_cast` of the form `static_cast<T>(e)` if the declaration
45
- `T t(e);` is well-formed, for some invented temporary variable `t` (
46
- [[dcl.init]]). The effect of such an explicit conversion is the same as
47
- performing the declaration and initialization and then using the
48
- temporary variable as the result of the conversion. The expression `e`
49
- is used as a glvalue if and only if the initialization uses it as a
50
- glvalue.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  Otherwise, the `static_cast` shall perform one of the conversions listed
53
  below. No other conversion shall be performed explicitly using a
54
  `static_cast`.
55
 
56
  Any expression can be explicitly converted to type cv `void`, in which
57
  case it becomes a discarded-value expression (Clause  [[expr]]).
58
- however, if the value is in a temporary object ([[class.temporary]]),
59
- the destructor for that object is not executed until the usual time, and
60
- the value of the object is preserved for the purpose of executing the
61
- destructor.
 
62
 
63
  The inverse of any standard conversion sequence (Clause  [[conv]]) not
64
  containing an lvalue-to-rvalue ([[conv.lval]]), array-to-pointer (
65
  [[conv.array]]), function-to-pointer ([[conv.func]]), null pointer (
66
- [[conv.ptr]]), null member pointer ([[conv.mem]]), or boolean (
67
- [[conv.bool]]) conversion, can be performed explicitly using
68
- `static_cast`. A program is ill-formed if it uses `static_cast` to
69
- perform the inverse of an ill-formed standard conversion sequence.
 
 
 
70
 
71
  ``` cpp
72
  struct B { };
73
  struct D : private B { };
74
  void f() {
75
- static_cast<D*>((B*)0); // Error: B is a private base of D.
76
- static_cast<int B::*>((int D::*)0); // Error: B is a private base of D.
77
  }
78
  ```
79
 
 
 
80
  The lvalue-to-rvalue ([[conv.lval]]), array-to-pointer (
81
  [[conv.array]]), and function-to-pointer ([[conv.func]]) conversions
82
  are applied to the operand. Such a `static_cast` is subject to the
83
  restriction that the explicit conversion does not cast away constness (
84
  [[expr.const.cast]]), and the following additional rules for specific
@@ -92,60 +112,67 @@ unchanged if the original value can be represented by the specified
92
  type. Otherwise, the resulting value is unspecified. A value of a scoped
93
  enumeration type can also be explicitly converted to a floating-point
94
  type; the result is the same as that of converting from the original
95
  value to the floating-point type.
96
 
97
- A value of integral or enumeration type can be explicitly converted to
98
- an enumeration type. The value is unchanged if the original value is
99
- within the range of the enumeration values ([[dcl.enum]]). Otherwise,
100
- the resulting value is unspecified (and might not be in that range). A
101
- value of floating-point type can also be explicitly converted to an
102
- enumeration type. The resulting value is the same as converting the
103
- original value to the underlying type of the enumeration (
104
- [[conv.fpint]]), and subsequently to the enumeration type.
105
 
106
- A prvalue of type “pointer to *cv1* `B`,” where `B` is a class type, can
107
- be converted to a prvalue of type “pointer to *cv2* `D`,” where `D` is a
108
- class derived (Clause  [[class.derived]]) from `B`, if a valid standard
109
- conversion from “pointer to `D`” to “pointer to `B` exists (
110
- [[conv.ptr]]), *cv2* is the same cv-qualification as, or greater
111
- cv-qualification than, *cv1*, and `B` is neither a virtual base class of
112
- `D` nor a base class of a virtual base class of `D`. The null pointer
113
- value ([[conv.ptr]]) is converted to the null pointer value of the
114
- destination type. If the prvalue of type “pointer to *cv1* `B`” points
115
- to a `B` that is actually a subobject of an object of type `D`, the
116
- resulting pointer points to the enclosing object of type `D`. Otherwise,
117
- the behavior is undefined.
118
 
119
  A prvalue of type “pointer to member of `D` of type *cv1* `T`” can be
120
- converted to a prvalue of type “pointer to member of `B` of type *cv2*
121
- `T`, where `B` is a base class (Clause  [[class.derived]]) of `D`, if a
122
- valid standard conversion from “pointer to member of `B` of type `T`” to
123
- “pointer to member of `D` of type `T`” exists ([[conv.mem]]), and *cv2*
124
- is the same cv-qualification as, or greater cv-qualification than,
125
- *cv1*.[^11] The null member pointer value ([[conv.mem]]) is converted
126
- to the null member pointer value of the destination type. If class `B`
127
- contains the original member, or is a base or derived class of the class
128
- containing the original member, the resulting pointer to member points
129
- to the original member. Otherwise, the behavior is undefined. although
130
- class `B` need not contain the original member, the dynamic type of the
131
- object with which indirection through the pointer to member is performed
132
- must contain the original member; see  [[expr.mptr.oper]].
 
 
 
133
 
134
  A prvalue of type “pointer to *cv1* `void`” can be converted to a
135
- prvalue of type “pointer to *cv2* `T`,” where `T` is an object type and
136
  *cv2* is the same cv-qualification as, or greater cv-qualification than,
137
- *cv1*. The null pointer value is converted to the null pointer value of
138
- the destination type. If the original pointer value represents the
139
- address `A` of a byte in memory and `A` satisfies the alignment
140
- requirement of `T`, then the resulting pointer value represents the same
141
- address as the original pointer value, that is, `A`. The result of any
142
- other such pointer conversion is unspecified. A value of type pointer to
143
- object converted to “pointer to *cv* `void`” and back, possibly with
144
- different cv-qualification, shall have its original value.
 
 
145
 
146
  ``` cpp
147
  T* p1 = new T;
148
  const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
149
  bool b = p1 == p2; // b will have the value true.
150
  ```
151
 
 
 
 
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.
22
+
23
+ [*Example 1*:
24
 
25
  ``` cpp
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 { };
91
  struct D : private B { };
92
  void f() {
93
+ static_cast<D*>((B*)0); // error: B is a private base of D
94
+ static_cast<int B::*>((int D::*)0); // error: B is a private base of D
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
 
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
158
+ prvalue of type “pointer to *cv2* `T`”, where `T` is an object type and
159
  *cv2* is the same cv-qualification as, or greater cv-qualification than,
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
 
171
  ``` cpp
172
  T* p1 = new T;
173
  const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
174
  bool b = p1 == p2; // b will have the value true.
175
  ```
176
 
177
+ — *end example*]
178
+