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

Jason House jason.james.house at gmail.com
Sun Jan 4 19:24:37 PST 2009


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;
unconsted[0][0] = 43;



More information about the Digitalmars-d mailing list