First Draft: cast(ref T)... as shorthand for *cast(T*)&...
IchorDev
zxinsworld at gmail.com
Mon Jan 20 09:07:03 UTC 2025
On Saturday, 18 January 2025 at 07:31:40 UTC, Walter Bright wrote:
> Proposed by Manu https://github.com/dlang/dmd/issues/20644
>
> PR: https://github.com/dlang/dmd/pull/20728
I would really like an actual DIP that I can read.
First: I think this type of cast should be `@safe` where
conservatively possible. For example, I can’t think of any reason
that casting from `int` to `float` in this way shouldn’t be
`@safe`. For structs it’s more complicated, but you could try to
check if both are POD, make sure the size is equal or less, etc.
Reinterpretation into `bool` is obviously always unsafe. ;)
Second: Is there a way to make this syntax also simplify these 2
similar patterns?
```d
T[] foo = (cast(T*)malloc(T.sizeof * n))[0..n];
```
```d
void[] foo = (cast(void*)&bar)[0..bar.sizeof];
```
Third: This is a long shot, but should we make it so that casting
to a larger type is `@safe` by populating the remaining space
with zeroes?
```d
short foo = 10;
auto baz = cast(ref int)foo; //remaining 2 bytes filled with
zeroes
```
It’s different from `cast(long)` in that the remaining bytes are
always filled with zero, and it would always be the *trailing*
bytes that are zero (on big endian systems, proper zero-extension
prepends the zeroed bytes, not appends):
LE sign extension via cast(int):
`0A 00` -> `0A 00 00 00`
BE sign extension via cast(int):
`00 0A` -> `00 00 00 0A`
LE cast(ref int):
`0A 00` -> `0A 00 00 00`
BE cast(ref int):
`00 0A` -> `00 0A 00 00`
I can see this being useful for esoteric byte order manipulation.
Moreso it’s actually useful for casting between struct types that
have ‘inheritance’.
More information about the dip.development
mailing list