Skip to content

Commit ca060ac

Browse files
ntreldlang-bot
authored andcommitted
Fix Bugzilla 19348 - Struct casts should be better documented
Document fallback casting from struct/static array to struct. Add example. Also add link to struct constructors for `T(args)` *PostfixExpression*.
1 parent 25f376c commit ca060ac

File tree

1 file changed

+31
-5
lines changed

1 file changed

+31
-5
lines changed

spec/expression.dd

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,13 +1547,38 @@ $(H4 $(LNAME2 cast_floating, Floating Point))
15471547

15481548
$(H4 $(LNAME2 cast_struct, Structs))
15491549

1550-
$(P Casting an expression $(I e) to a struct $(I S), when the
1551-
expression is not a struct of the same type, is equivalent to a
1552-
$(GLINK PostfixExpression):)
1550+
$(P An expression `e` can be cast to a struct type `S`:)
15531551

1552+
* The compiler attempts a
1553+
$(RELATIVE_LINK2 type-constructor-arguments, *PostfixExpression*) `S(e)`.
1554+
If that would fail:
1555+
* When `e` is a struct or static array instance, its data is reinterpreted as
1556+
the target type `S`. The data sizes must match.
1557+
* Otherwise, it is an error.
1558+
1559+
$(SPEC_RUNNABLE_EXAMPLE_RUN
15541560
---
1555-
S(e)
1561+
struct S
1562+
{
1563+
int i;
1564+
}
1565+
struct R
1566+
{
1567+
short[2] a;
1568+
}
1569+
1570+
S s = cast(S) 5; // same as S(5)
1571+
assert(s.i == 5);
1572+
static assert(!__traits(compiles, cast(S) long.max)); // S(long.max) is invalid
1573+
1574+
R r = R([1, 2]);
1575+
s = cast(S) r; // reinterpret r
1576+
assert(s.i == 0x00020001);
1577+
1578+
byte[4] a = [1, 0, 2, 0];
1579+
assert(r == cast(R) a); // reinterpret a
15561580
---
1581+
)
15571582

15581583
$(P A struct instance can be cast to a static array type when
15591584
their `.sizeof` properties each give the same result.)
@@ -1563,7 +1588,7 @@ $(H4 $(LNAME2 cast_struct, Structs))
15631588
struct S { short a, b, c; }
15641589

15651590
S s = S(1, 2, 3);
1566-
static assert(!__traits(compiles, cast(short[2]) s));
1591+
static assert(!__traits(compiles, cast(short[2]) s)); // size mismatch
15671592

15681593
short[3] x = cast(short[3]) s;
15691594
assert(x.tupleof == s.tupleof);
@@ -1775,6 +1800,7 @@ $(H4 $(LNAME2 type-constructor-arguments, Constructing a Type with an Argument L
17751800
$(P A type can precede a list of arguments. See:)
17761801

17771802
* $(DDSUBLINK spec/struct, struct-literal, Struct Literals)
1803+
* $(DDSUBLINK spec/struct, struct-constructor, Struct Constructors)
17781804
* $(RELATIVE_LINK2 uniform_construction_syntax, Uniform construction syntax for built-in scalar types)
17791805

17801806
$(H3 $(LEGACY_LNAME2 index_operations, index_expressions, Index Operations))

0 commit comments

Comments
 (0)