Feature: `static cast`

Quirin Schroll qs.il.paperinik at gmail.com
Thu Jun 1 14:13:27 UTC 2023


In short, `static cast` would be exactly like C++’s `static_cast` 
when used with class-type pointers or references, however, D’s 
`static cast` cannot be used with anything else, i.e. D’s `static 
cast` can’t cast `double` to `int`.

---

Introduce `static cast(Type) UnaryExpression` with the following 
semantics: If `Type` and `typeof(UnaryExpression)` are class or 
interface types, it casts UnaryExpression to `Type` without 
checks; only the underlying pointer is adjusted if needed. It is 
invalid if there is no unique way to do it or if the types aren’t 
class or interface types in the first place.

There are two use-cases:
1. It gives programmers the option to express: “I know by other 
means that the cast will succeed, so just do it.” If by the type 
system, there is no guarantee it will succeed, i.e. it’s a 
down-cast, that is un-`@safe`.
2. It won’t trick unaware programmers into thinking that [the 
following](https://dlang.org/spec/expression.html#cast_class) 
applies when it doesn’t: “Any casting of a class reference to a 
derived class reference is done with a runtime check to make sure 
it really is a downcast. `null` is the result if it isn’t.”

There’s at least once case where I got bitten by 2. and it cost 
me days to figure out that, contrary to the spec, casting between 
`extern(C++)` class references isn’t checked at runtime:
```d
extern(C++) class C { void f() { } }
extern(C++) class D : C { }
void main() @safe
{
     assert(cast(D)(new C) is null); // fails
}
```
With `extern(D)`, the assertion passes. With a `static assert`, 
it passes as well.

There are two issues with the cast in the code snippet:
1. It is considered `@safe` when it’s not actually safe.
2. Even if it weren’t safe, there should be an indication that 
the cast isn’t a safe, dynamically checked cast.

Introducing `static cast` can solve both of them. It wouldn’t be 
`@safe` in this case and it indicates that the cast isn’t 
dynamically checked. Also, in this case, it would be an error not 
to use it until [issue 21690 (Unable to dynamic cast 
`extern(C++)` 
classes)](https://issues.dlang.org/show_bug.cgi?id=21690) is 
solved.


More information about the Digitalmars-d mailing list