From Jason Turner

[expr.static.cast]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp8ggxh04x/{from.md → to.md} +36 -25
tmp/tmp8ggxh04x/{from.md → to.md} RENAMED
@@ -16,30 +16,34 @@ 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 result of the cast 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 of type “*cv1* `T1`” can be cast to type “rvalue reference to
33
- *cv2* `T2`” if “*cv2* `T2`” is reference-compatible with “*cv1* `T1`” (
34
- [[dcl.init.ref]]). The result refers to the object or the specified base
35
- class subobject thereof. If `T2` is an inaccessible (Clause 
 
 
 
 
36
  [[class.access]]) or ambiguous ([[class.member.lookup]]) base class of
37
  `T1`, a program that necessitates such a cast is ill-formed.
38
 
39
- Otherwise, an expression `e` can be explicitly converted to a type `T`
40
- using a `static_cast` of the form `static_cast<T>(e)` if the declaration
41
  `T t(e);` is well-formed, for some invented temporary variable `t` (
42
  [[dcl.init]]). The effect of such an explicit conversion is the same as
43
  performing the declaration and initialization and then using the
44
  temporary variable as the result of the conversion. The expression `e`
45
  is used as a glvalue if and only if the initialization uses it as a
@@ -79,24 +83,27 @@ are applied to the operand. Such a `static_cast` is subject to the
79
  restriction that the explicit conversion does not cast away constness (
80
  [[expr.const.cast]]), and the following additional rules for specific
81
  cases:
82
 
83
  A value of a scoped enumeration type ([[dcl.enum]]) can be explicitly
84
- converted to an integral type. The value is unchanged if the original
85
- value can be represented by the specified type. Otherwise, the resulting
86
- value is unspecified. A value of a scoped enumeration type can also be
87
- explicitly converted to a floating-point type; the result is the same as
88
- that of converting from the original value to the floating-point type.
 
 
 
89
 
90
  A value of integral or enumeration type can be explicitly converted to
91
  an enumeration type. The value is unchanged if the original value is
92
  within the range of the enumeration values ([[dcl.enum]]). Otherwise,
93
  the resulting value is unspecified (and might not be in that range). A
94
- value of floating-point type can also be converted to an enumeration
95
- type. The resulting value is the same as converting the original value
96
- to the underlying type of the enumeration ([[conv.fpint]]), and
97
- subsequently to the enumeration type.
98
 
99
  A prvalue of type “pointer to *cv1* `B`,” where `B` is a class type, can
100
  be converted to a prvalue of type “pointer to *cv2* `D`,” where `D` is a
101
  class derived (Clause  [[class.derived]]) from `B`, if a valid standard
102
  conversion from “pointer to `D`” to “pointer to `B`” exists (
@@ -105,34 +112,38 @@ cv-qualification than, *cv1*, and `B` is neither a virtual base class of
105
  `D` nor a base class of a virtual base class of `D`. The null pointer
106
  value ([[conv.ptr]]) is converted to the null pointer value of the
107
  destination type. If the prvalue of type “pointer to *cv1* `B`” points
108
  to a `B` that is actually a subobject of an object of type `D`, the
109
  resulting pointer points to the enclosing object of type `D`. Otherwise,
110
- the result of the cast is undefined.
111
 
112
  A prvalue of type “pointer to member of `D` of type *cv1* `T`” can be
113
  converted to a prvalue of type “pointer to member of `B`” of type *cv2*
114
  `T`, where `B` is a base class (Clause  [[class.derived]]) of `D`, if a
115
  valid standard conversion from “pointer to member of `B` of type `T`” to
116
  “pointer to member of `D` of type `T`” exists ([[conv.mem]]), and *cv2*
117
  is the same cv-qualification as, or greater cv-qualification than,
118
- *cv1*.[^12] The null member pointer value ([[conv.mem]]) is converted
119
  to the null member pointer value of the destination type. If class `B`
120
  contains the original member, or is a base or derived class of the class
121
  containing the original member, the resulting pointer to member points
122
- to the original member. Otherwise, the result of the cast is undefined.
123
- although class `B` need not contain the original member, the dynamic
124
- type of the object on which the pointer to member is dereferenced must
125
- contain the original member; see  [[expr.mptr.oper]].
126
 
127
  A prvalue of type “pointer to *cv1* `void`” can be converted to a
128
  prvalue of type “pointer to *cv2* `T`,” where `T` is an object type and
129
  *cv2* is the same cv-qualification as, or greater cv-qualification than,
130
  *cv1*. The null pointer value is converted to the null pointer value of
131
- the destination type. A value of type pointer to object converted to
132
- “pointer to *cv* `void` and back, possibly with different
133
- cv-qualification, shall have its original value.
 
 
 
 
134
 
135
  ``` cpp
136
  T* p1 = new T;
137
  const T* p2 = static_cast<const T*>(static_cast<void*>(p1));
138
  bool b = p1 == p2; // b will have the value true.
 
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
 
83
  restriction that the explicit conversion does not cast away constness (
84
  [[expr.const.cast]]), and the following additional rules for specific
85
  cases:
86
 
87
  A value of a scoped enumeration type ([[dcl.enum]]) can be explicitly
88
+ converted to an integral type. When that type is cv `bool`, the
89
+ resulting value is `false` if the original value is zero and `true` for
90
+ all other values. For the remaining integral types, the value is
91
+ 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 (
 
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.