https://issues.dlang.org/show_bug.cgi?id=21690
Bolpat <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |[email protected] --- Comment #14 from Bolpat <[email protected]> --- (In reply to kinke from comment #1) > So while getting proper dynamic casts working is probably quite hard, we > could probably disallow downcasts like this and require an explicit static > cast (`cast(CC) cast(void*) ca`)? In C++ terminology at least, this isn’t a `static_cast`, but a `reinterpret_cast`. It works when you only have single inheritance (counting interfaces as inheritance as well). As soon as any form of multiple inheritance (including interfaces) enters the picture, `cast(void*)` won’t do what you want. There are simple, but relevant, pointer value adjustments at play. Example: ```d import std.stdio; extern(C++) abstract class B { int x; abstract void f(); } extern(C++) interface I { void g(); } extern(C++) class D : B, I { override void f() => writeln("f"); override void g() => writeln("g"); } void main() { D d = new D; void* bptr = cast(void*) cast(B) d; void* iptr = cast(void*) cast(I) d; assert(bptr !is iptr); // passes void* vptr = cast(void*) d; B b = cast(B) vptr; I i = cast(I) vptr; b.f(); // prints f as expected i.g(); // should print g, on run.dlang.org, prints f as well } ``` The `extern(C++)` has little to do with it; with `extern(D)` the problems persist. As far as I know, for class handles, it’s syntactically impossible to express a C++ `static_cast` in D; it’s a `dynamic_cast` or – if you go via `void*` – it’s a `reinterpret_cast`. Of course, a derived-to-base `dynamic_cast` can be optimized to be a `static_cast`, but there’s no way to tell the compiler: I *know* this base-class object is in fact a derived object, so adjust the pointer accordingly (and don’t check TypeInfo or whatever and give me UB if I’m wrong). A simple solution would be to introduce `static cast(Type) UnaryExpression` for that. It would be valid only if `Type` and the type of `UnaryExpression` are both a class or interface type, which have a unique inheritance relationship. --
