@@ -1073,34 +1073,42 @@ $(H3 $(LNAME2 cast_expressions, Cast Expressions))
1073
1073
$(GRAMMAR
1074
1074
$(GNAME CastExpression):
1075
1075
$(D cast $(LPAREN)) $(GLINK2 type, Type) $(D $(RPAREN)) $(GLINK UnaryExpression)
1076
- $(D cast $(LPAREN)) $(GLINK2 type, TypeCtors)$(OPT) $(D $(RPAREN)) $( GLINK UnaryExpression )
1076
+ $(GLINK CastQual )
1077
1077
)
1078
1078
1079
1079
$(P A $(I CastExpression) converts the $(I UnaryExpression)
1080
- to $(GLINK2 type, Type).)
1080
+ to $(I Type).)
1081
1081
1082
1082
-------------
1083
1083
cast(foo) -p; // cast (-p) to type foo
1084
1084
(foo) - p; // subtract p from foo
1085
1085
-------------
1086
1086
1087
+ $(H4 $(LNAME2 cast_class, Class References))
1088
+
1087
1089
$(P Any casting of a class reference to a
1088
1090
derived class reference is done with a runtime check to make sure it
1089
1091
really is a downcast. $(D null) is the result if it isn't.
1090
1092
)
1091
1093
1094
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
1092
1095
-------------
1093
- class A { ... }
1094
- class B : A { ... }
1096
+ class A {}
1097
+ class B : A {}
1095
1098
1096
- void test(A a, B b )
1099
+ void main( )
1097
1100
{
1098
- B bx = a; // error, need cast
1099
- B bx = cast(B) a; // bx is null if a is not a B
1100
- A ax = b; // no cast needed
1101
- A ax = cast(A) b; // no runtime check needed for upcast
1101
+ A a = new A;
1102
+ //B b = a; // error, need cast
1103
+ B b = cast(B) a; // b is null if a is not a B
1104
+ assert(b is null);
1105
+
1106
+ a = b; // no cast needed
1107
+ a = cast(A) b; // no runtime check needed for upcast
1108
+ assert(a is b);
1102
1109
}
1103
1110
-------------
1111
+ )
1104
1112
1105
1113
$(P In order to determine if an object $(D o) is an instance of
1106
1114
a class $(D B) use a cast:)
@@ -1120,52 +1128,54 @@ $(GNAME CastExpression):
1120
1128
(i.e. a reinterpret cast).
1121
1129
)
1122
1130
1131
+ $(H4 $(LNAME2 cast_array, Arrays))
1132
+
1123
1133
$(P Casting a dynamic array to another dynamic array is done only if the
1124
1134
array lengths multiplied by the element sizes match. The cast is done
1125
1135
as a type paint, with the array length adjusted to match any change in
1126
1136
element size. If there's not a match, a runtime error is generated.)
1127
1137
1128
- ---
1129
- import std.stdio;
1130
-
1131
- int main()
1132
- {
1138
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
1139
+ ---
1133
1140
byte[] a = [1,2,3];
1134
- auto b = cast(int[])a; // runtime array cast misalignment
1141
+ // auto b = cast(int[])a; // runtime error: array cast misalignment
1135
1142
1136
1143
int[] c = [1, 2, 3];
1137
1144
auto d = cast(byte[])c; // ok
1138
1145
// prints:
1139
1146
// [1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]
1140
1147
writeln(d);
1141
- return 0;
1142
- }
1143
- ---
1148
+ ---
1149
+ )
1150
+
1151
+ $(DDOC_SEE_ALSO $(RELATIVE_LINK2 cast_array_literal, Casting array literals).)
1144
1152
1153
+ $(H4 $(LNAME2 cast_static_array, Static Arrays))
1145
1154
1146
1155
$(P Casting a static array to another static array is done only if the
1147
1156
array lengths multiplied by the element sizes match; a mismatch
1148
1157
is illegal.
1149
1158
The cast is done as a type paint (aka a reinterpret cast).
1150
1159
The contents of the array are not changed.)
1151
1160
1152
- ---
1153
- import core.stdc.stdio;
1154
-
1155
- void main()
1156
- {
1157
- byte[16] b = 3;
1161
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
1162
+ ---
1163
+ byte[16] b = 3; // set each element to 3
1164
+ assert(b[0] == 0x03);
1158
1165
int[4] ia = cast(int[4]) b;
1166
+ // print elements as hex
1159
1167
foreach (i; ia)
1160
- printf ("%x\n ", i);
1168
+ writefln ("%x", i);
1161
1169
/* prints:
1162
1170
3030303
1163
1171
3030303
1164
1172
3030303
1165
1173
3030303
1166
1174
*/
1167
- }
1168
- ---
1175
+ ---
1176
+ )
1177
+
1178
+ $(H4 $(LNAME2 cast_floating, Floating Point))
1169
1179
1170
1180
$(P Casting a floating point literal from one type to another
1171
1181
changes its type, but internally it is retained at full
@@ -1217,40 +1227,55 @@ $(GNAME CastExpression):
1217
1227
}
1218
1228
---
1219
1229
1230
+ $(H4 $(LNAME2 cast_struct, Structs))
1231
+
1220
1232
$(P Casting a value $(I v) to a struct $(I S), when value is not a struct
1221
1233
of the same type, is equivalent to:)
1222
1234
1223
1235
---
1224
1236
S(v)
1225
1237
---
1226
1238
1227
- $(P Casting to a $(GLINK CastQual) replaces the qualifiers to the type of
1228
- the $(GLINK UnaryExpression).)
1239
+ $(H4 $(LNAME2 cast_qualifier, Qualifier Cast))
1240
+
1241
+ $(GRAMMAR
1242
+ $(GNAME CastQual):
1243
+ $(D cast $(LPAREN)) $(GLINK2 type, TypeCtors)$(OPT) $(D $(RPAREN)) $(GLINK UnaryExpression)
1244
+ )
1229
1245
1246
+ $(P A $(I CastQual) replaces the qualifiers in the type of
1247
+ the $(I UnaryExpression):)
1248
+
1249
+ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
1230
1250
---
1231
1251
shared int x;
1232
- assert(is(typeof(cast(const)x) == const int));
1252
+ static assert(is(typeof(cast(const)x) == const int));
1233
1253
---
1254
+ )
1234
1255
1235
- $(P Casting with no $(GLINK2 type, Type) or $(GLINK CastQual) removes
1256
+ $(P Casting with no type or qualifiers removes
1236
1257
any top level $(D const), $(D immutable), $(D shared) or $(D inout)
1237
1258
type modifiers from the type
1238
- of the $(GLINK UnaryExpression).)
1259
+ of the $(I UnaryExpression).)
1239
1260
1261
+ $(SPEC_RUNNABLE_EXAMPLE_COMPILE
1240
1262
---
1241
1263
shared int x;
1242
- assert(is(typeof(cast()x) == int));
1264
+ static assert(is(typeof(cast()x) == int));
1243
1265
---
1266
+ )
1267
+
1268
+ $(H4 $(LNAME2 cast_void, Casting to `void`))
1244
1269
1245
1270
$(P Casting an expression to $(D void) type is allowed to mark that
1246
1271
the result is unused. On $(GLINK2 statement, ExpressionStatement),
1247
- it could be used properly to avoid "has no effect" error.)
1272
+ it could be used properly to avoid a "has no effect" error.)
1248
1273
1249
1274
----
1250
1275
void foo(lazy void exp) {}
1251
1276
void main()
1252
1277
{
1253
- foo(10); // NG - has no effect in expression '10'
1278
+ foo(10); // NG - expression '10' has no effect
1254
1279
foo(cast(void)10); // OK
1255
1280
}
1256
1281
----
@@ -1644,11 +1669,14 @@ $(GNAME ArrayLiteral):
1644
1669
}
1645
1670
---
1646
1671
1672
+ $(H3 $(LNAME2 cast_array_literal, Casting))
1673
+
1647
1674
$(P When array literals are cast to another array type, each
1648
1675
element of the array is cast to the new element type.
1649
- When arrays that are not literals are cast, the array is
1676
+ When arrays that are not literals $(RELATIVE_LINK2 cast_array, are cast) , the array is
1650
1677
reinterpreted as the new type, and the length is recomputed:)
1651
1678
1679
+ $(SPEC_RUNNABLE_EXAMPLE_RUN
1652
1680
---
1653
1681
import std.stdio;
1654
1682
@@ -1667,6 +1695,7 @@ $(GNAME ArrayLiteral):
1667
1695
writeln(rt); // writes [257]
1668
1696
}
1669
1697
---
1698
+ )
1670
1699
1671
1700
In other words, casting an array literal will change the type of each initializer element.
1672
1701
0 commit comments