Possible D2 solution to the upcasting array problem, and a related problem with const and nested arrays

Denis Koroskin 2korden at gmail.com
Sun Jan 4 19:42:09 PST 2009


On Mon, 05 Jan 2009 06:24:37 +0300, Jason House <jason.james.house at gmail.com> wrote:

> Denis Koroskin wrote:
>
>> On Mon, 05 Jan 2009 04:16:43 +0300, Jason House
>> <jason.james.house at gmail.com> wrote:
>>
>>> Stewart Gordon wrote:
>>>
>>>> I was just looking at this
>>>> http://d.puremagic.com/issues/show_bug.cgi?id=2544
>>>> which describes how it's possible to bypass const by doing this:
>>>>
>>>>      const(int)[] answers = [42];
>>>>      int[][] unconsted = [[]];
>>>>      const(int)[][] unsafe = unconsted;
>>>>      unsafe[0] = answers;
>>>>      unconsted[0][0] = 43;
>>>>
>>>> The problem is that converting from int[][] to const(int)[][] isn't
>>>> safe, even though the language/compiler seems to think it is.
>>>>
>>>> Really, it's another version of how you can use a DerivedClass[] as a
>>>> BaseClass[] and thereby place in it an object that isn't of type
>>>> DerivedClass.
>>>>
>>>> There's actually a simple solution to this: specify that, where
>>>> DerivedClass derives from BaseClass, DerivedClass[] cannot be  
>>>> implicitly
>>>> converted to BaseClass[], but only to const(BaseClass)[].
>>>>
>>>> Java has had something like this for a while, albeit not with arrays.
>>>> That is, IIRC, you can assign a DataStructure<DerivedClass> to a
>>>> variable of type DataStructure<? extends BaseClass> (or even
>>>> DataStructure<? extends DerivedClass>) - this creates a read-only view
>>>> of the data structure.  My proposal implements the same basic concept  
>>>> as
>>>> this, but in a simpler way.  (Java also supports write-only 'views'  
>>>> with
>>>> DataStructure<? super FurtherDerivedClass>, but I'm not sure we need
>>>> anything like this in D at the moment.)
>>>>
>>>> Now let's apply the same principle to the example in the bug report.
>>>> Try defining that, in general, T[][] can be converted to const(T[])[]
>>>> but not const(T)[][].  Then
>>>>
>>>>      const(int)[] answers = [42];
>>>>      int[][] unconsted = [[]];
>>>>      const(int)[][] unsafe = unconsted;
>>>>
>>>> would be illegal.  One would have to do
>>>>
>>>>      const(int[])[] safe = unconsted;
>>>>
>>>> and now
>>>>
>>>>      safe[0] = answers;
>>>>
>>>> is illegal.
>>>
>>> What about this code?
>>> const int[] answers = [42];
>>> int[][] unconsted = [[]];
>>> const(int[])[] safe = unconsted;
>>> safe[0] = answers;
>>> safe[0][0] = 43;
>>
>> Err... "safe[0][0] = 43;" shouldn't compile (it's const)
>
> Oops... The following is what I meant.  unconsted should be used to  
> change the content of answers:
>
> What about this code?
> const int[] answers = [42];
> int[][] unconsted = [[]];
> const(int[])[] safe = unconsted;
> safe[0] = answers;

You can't mutate safe because it is const.

> unconsted[0][0] = 43;



More information about the Digitalmars-d mailing list