www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - cast overly permissive with extern(C++ ) classes;

reply Timothee Cour <thelastmammoth gmail.com> writes:
should we force force casting through `void*` for extern(C++) classes ?
i.e. `cast(Derived) cast(void*) base_instance;`

currently, `cast(A) unrelad_cpp_instance` happily compiles but
shouldn't, it's very error prone even though the cast syntax suggests
type safety; especially a problem if we make a class become
extern(C++) in the future

[came up after discussing with jacob-carlborg]
Feb 06 2018
parent reply timotheecour <timothee.cour2 gmail.com> writes:
On Tuesday, 6 February 2018 at 20:39:09 UTC, Timothee Cour wrote:
 should we force force casting through `void*` for extern(C++) 
 classes ?
 i.e. `cast(Derived) cast(void*) base_instance;`

 currently, `cast(A) unrelad_cpp_instance` happily compiles but 
 shouldn't, it's very error prone even though the cast syntax 
 suggests type safety; especially a problem if we make a class 
 become extern(C++) in the future

 [came up after discussing with jacob-carlborg]
https://run.dlang.io/?compiler=dmd&source=import%20std.stdio;%0Aclass%20Foo%20%7B%7D%0A%0Avoid%20main()%0A%7B%0A%09auto%20f%20%3D%20new%20const%20Foo;%0A%20%20%20%20pragma(msg,%20typeof(cast(Foo)%20f));%0A%7D ``` import std.stdio; extern(C++){ class Base {void ignore(){}} class Derived : Base {} class C {} } void main() { Base f = new Derived; auto temp=cast(C)f; writeln(temp is null); // false, which is not good } ```
Feb 06 2018
parent reply timotheecour <timothee.cour2 gmail.com> writes:
On Tuesday, 6 February 2018 at 21:13:50 UTC, timotheecour wrote:
 On Tuesday, 6 February 2018 at 20:39:09 UTC, Timothee Cour 
 wrote:
 should we force force casting through `void*` for extern(C++) 
 classes ?
 i.e. `cast(Derived) cast(void*) base_instance;`

 currently, `cast(A) unrelad_cpp_instance` happily compiles but 
 shouldn't, it's very error prone even though the cast syntax 
 suggests type safety; especially a problem if we make a class 
 become extern(C++) in the future

 [came up after discussing with jacob-carlborg]
Actually how about introducing a library solution for explicit casting: * works with UFCS chains (unlike cast) * DSL is very intuitive, readable and extensible ``` foo.Cast!"+immutable,dynamic" myint.cast!"-const,"unsigned" ``` meaning: +immutable: make immutable; -const: remove const storage class if was const; dynamic: only allow dynamic cast (cf avoids above bug); unsigned: cast integer to unsigned; other keywords could be trivially added to DSL alternative is not DRY (eg: `Foo foo; cast(const(Foo)) foo;` ; not typesafe/expressive: (cast(Foo)foo) will remove const-ness in foo even though just a dynamic cast was intended for eg; and doesn't work in UFCS chains (requires lots of parenthesis)
Feb 06 2018
parent reply Seb <seb wilzba.ch> writes:
On Tuesday, 6 February 2018 at 21:34:07 UTC, timotheecour wrote:
 On Tuesday, 6 February 2018 at 21:13:50 UTC, timotheecour wrote:
[...]
Actually how about introducing a library solution for explicit casting: * works with UFCS chains (unlike cast) * DSL is very intuitive, readable and extensible [...]
Like assumeUnique? https://dlang.org/library/std/exception/assume_unique.html
Feb 06 2018
parent reply Timothee Cour <thelastmammoth gmail.com> writes:
 Like assumeUnique?
https://dlang.org/library/std/exception/assume_unique.html what do you mean? u mean adding "unique" to the DSL list ? maybe! * for cast on extern C++ classes, why not use the same logic as what C++ uses for dynamic_cast? (simplified because we don't support multople inheritance) On Tue, Feb 6, 2018 at 2:54 PM, Seb via Digitalmars-d <digitalmars-d puremagic.com> wrote:
 On Tuesday, 6 February 2018 at 21:34:07 UTC, timotheecour wrote:
 On Tuesday, 6 February 2018 at 21:13:50 UTC, timotheecour wrote:
 [...]
Actually how about introducing a library solution for explicit casting: * works with UFCS chains (unlike cast) * DSL is very intuitive, readable and extensible [...]
Like assumeUnique? https://dlang.org/library/std/exception/assume_unique.html
Feb 06 2018
parent reply Seb <seb wilzba.ch> writes:
On Tuesday, 6 February 2018 at 23:15:07 UTC, Timothee Cour wrote:
 Like assumeUnique?
https://dlang.org/library/std/exception/assume_unique.html what do you mean? u mean adding "unique" to the DSL list ? maybe!
You asked: Actually how about introducing a library solution for explicit casting. That's why I thought about the existing assumeUnique: ``` immutable(T)[] assumeUnique(T)(ref T[] array) pure nothrow { auto result = cast(immutable(T)[]) array; array = null; return result; } ``` https://github.com/dlang/phobos/blob/v2.078.1/std/exception.d#L905
Feb 06 2018
next sibling parent Timothee Cour <thelastmammoth gmail.com> writes:
assumeUnique has a very specific use case; i was describing a more
general way to handle various types of cast (and be explicit about
whats allowed) as mentioned above

On Tue, Feb 6, 2018 at 3:18 PM, Seb via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Tuesday, 6 February 2018 at 23:15:07 UTC, Timothee Cour wrote:
 Like assumeUnique?
https://dlang.org/library/std/exception/assume_unique.html what do you mean? u mean adding "unique" to the DSL list ? maybe!
You asked: Actually how about introducing a library solution for explicit casting. That's why I thought about the existing assumeUnique: ``` immutable(T)[] assumeUnique(T)(ref T[] array) pure nothrow { auto result = cast(immutable(T)[]) array; array = null; return result; } ``` https://github.com/dlang/phobos/blob/v2.078.1/std/exception.d#L905
Feb 06 2018
prev sibling parent reply Timothee Cour <thelastmammoth gmail.com> writes:
but yes, API would look similar:

auto Cast(T)(T a) if(...) {}
auto Cast(string dsl)(T a) {}

On Tue, Feb 6, 2018 at 3:31 PM, Timothee Cour <thelastmammoth gmail.com> wrote:
 assumeUnique has a very specific use case; i was describing a more
 general way to handle various types of cast (and be explicit about
 whats allowed) as mentioned above

 On Tue, Feb 6, 2018 at 3:18 PM, Seb via Digitalmars-d
 <digitalmars-d puremagic.com> wrote:
 On Tuesday, 6 February 2018 at 23:15:07 UTC, Timothee Cour wrote:
 Like assumeUnique?
https://dlang.org/library/std/exception/assume_unique.html what do you mean? u mean adding "unique" to the DSL list ? maybe!
You asked: Actually how about introducing a library solution for explicit casting. That's why I thought about the existing assumeUnique: ``` immutable(T)[] assumeUnique(T)(ref T[] array) pure nothrow { auto result = cast(immutable(T)[]) array; array = null; return result; } ``` https://github.com/dlang/phobos/blob/v2.078.1/std/exception.d#L905
Feb 06 2018
parent reply Seb <seb wilzba.ch> writes:
On Tuesday, 6 February 2018 at 23:32:49 UTC, Timothee Cour wrote:
 but yes, API would look similar:

 auto Cast(T)(T a) if(...) {}
 auto Cast(string dsl)(T a) {}
Ah I see. I think this is already partially done in Phobos (which shows the usefulness): https://github.com/dlang/phobos/blob/master/std/experimental/typecons.d#L37
Feb 06 2018
parent Timothee Cour <thelastmammoth gmail.com> writes:
ugh... dynamicCast is private...

On Tue, Feb 6, 2018 at 5:13 PM, Seb via Digitalmars-d
<digitalmars-d puremagic.com> wrote:
 On Tuesday, 6 February 2018 at 23:32:49 UTC, Timothee Cour wrote:
 but yes, API would look similar:

 auto Cast(T)(T a) if(...) {}
 auto Cast(string dsl)(T a) {}
Ah I see. I think this is already partially done in Phobos (which shows the usefulness): https://github.com/dlang/phobos/blob/master/std/experimental/typecons.d#L37
Feb 06 2018