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