March 11, 2021 [Issue 21690] Unable to dynamic cast extern(C++) classes | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=21690 Basile-z <b2.temp@gmx.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |b2.temp@gmx.com --- Comment #11 from Basile-z <b2.temp@gmx.com> --- Very hypothetically, let's say that if "super" calls are supported in C++ classes then this means that maybe the super virtual table is stored somewhere. If so then full dynamic casts would be possible. Someone needs to study a bit more the ABI of extern(C++) classes in D. Then maybe a dedicated dyncast() could be added to druntime. -- |
June 07, 2021 [Issue 21690] Unable to dynamic cast extern(C++) classes | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=21690 --- Comment #12 from Basile-z <b2.temp@gmx.com> --- (In reply to Basile-z from comment #11) > Very hypothetically, let's say that if "super" calls are supported in C++ classes then this means that maybe the super virtual table is stored somewhere. If so then full dynamic casts would be possible. > this supplemental comment was BS. Obviously `super` does not use the vtable. > Someone needs to study a bit more the ABI of extern(C++) classes in D. > Then maybe a dedicated dyncast() could be added to druntime. -- |
June 07, 2021 [Issue 21690] Unable to dynamic cast extern(C++) classes | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=21690 --- Comment #13 from Basile-z <b2.temp@gmx.com> --- (In reply to thomas.bockman from comment #10) > However, it seems a little too unpredictable and limited to be worth implementing in the compiler itself, given that kinke mentioned earlier that two instances of the same class may still end up pointing to different vtable addresses if they were instantiated on different sides of the language barrier: > > (kinke from comment #1) > > But then again, when we are confronted with some C++ class ref, we have no idea whether it was instantiated on the D side or C++ side and so which vtable its vptr points to. Major problem indeed. -- |
June 04, 2022 [Issue 21690] Unable to dynamic cast extern(C++) classes | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=21690 Walter Bright <bugzilla@digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |safe CC| |bugzilla@digitalmars.com -- |
December 17, 2022 [Issue 21690] Unable to dynamic cast extern(C++) classes | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=21690 Iain Buclaw <ibuclaw@gdcproject.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P1 |P2 -- |
June 01, 2023 [Issue 21690] Unable to dynamic cast extern(C++) classes | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=21690 Bolpat <qs.il.paperinik@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |qs.il.paperinik@gmail.com --- Comment #14 from Bolpat <qs.il.paperinik@gmail.com> --- (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. -- |
June 03, 2023 [Issue 21690] Unable to dynamic cast extern(C++) classes | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=21690 --- Comment #15 from Dlang Bot <dlang-bot@dlang.rocks> --- @ntrel created dlang/dmd pull request #15293 "Disallow dynamic cast on extern(C++) class" mentioning this issue: - Disallow dynamic cast on extern(C++) class See Issue 21690 - Unable to dynamic cast extern(C++) classes. https://github.com/dlang/dmd/pull/15293 -- |
June 03, 2023 [Issue 21690] Unable to dynamic cast extern(C++) classes | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=21690 Nick Treleaven <nick@geany.org> changed: What |Removed |Added ---------------------------------------------------------------------------- See Also| |https://issues.dlang.org/sh | |ow_bug.cgi?id=23957 -- |
Copyright © 1999-2021 by the D Language Foundation