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