Denis Koroskin wrote: > On Mon, 05 Jan 2009 04:16:43 +0300, Jason House > <[email protected]> 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;
