Thread overview
cast overly permissive with extern(C++ ) classes; should cast through `void*`
Feb 06, 2018
Timothee Cour
Feb 06, 2018
timotheecour
Feb 06, 2018
timotheecour
Feb 06, 2018
Seb
Feb 06, 2018
Timothee Cour
Feb 06, 2018
Seb
Feb 06, 2018
Timothee Cour
Feb 06, 2018
Timothee Cour
Feb 07, 2018
Seb
Feb 07, 2018
Timothee Cour
February 06, 2018
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]
February 06, 2018
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
}
```
February 06, 2018
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)

February 06, 2018
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
February 06, 2018
> 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
February 06, 2018
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
February 06, 2018
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
February 06, 2018
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
February 07, 2018
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
February 06, 2018
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