Limits of implicit conversion of class arrays

Steven Schveighoffer schveiguy at gmail.com
Thu Mar 28 01:53:52 UTC 2024


On Monday, 25 March 2024 at 07:16:35 UTC, Per Nordlöw wrote:
> On Saturday, 23 March 2024 at 11:04:04 UTC, Dmitry Olshansky 
> wrote:
>> The first and second is unsound (infamously allowed in Java).
>
> In the general case, yes. But, do you see any errors with the 
> code
>
> ```d
> class Base {}
> class Derived : Base {}
>
> @safe pure nothrow unittest {
> 	Base b;
> 	Derived d;
> 	b = d; // pass
>
> 	Base[] bs;
> 	Derived[] ds;
> 	bs ~= ds; // pass
> 	bs = ds; // fail [1], should pass
> 	bs = cast(Base[])ds; // fail [2], should pass
> }
> ```

Yes, it's unsafe, as you can replace an element of `ds` with 
something that has no relation to `Derived`.

>
>> Once you cast the slice you can populate it with Derived2 
>> objects that are not Derived, hence breaking type safety of 
>> the ds slice.
>
> Again, in the general case, yes.
>
> So what is different in this code example compared to the 
> general case? Hint: this has overlaps with a missing compiler 
> optimization in dmd (and many other statically typed languages) 
> enabled by a specific kind of data flow analysis. Which one?

If there is a way to end up with a `Derived` reference to point 
at something that is not a `Derived` *without a cast* in system 
code, or *even with a cast* in safe code, then it is an error. It 
doesn't matter if you aren't actually doing it.

If you know you are not making that mistake, change it to system, 
and cast to inform the compiler that you "know what you are 
doing".

-Steve


More information about the Digitalmars-d-learn mailing list