Comment #0 by bearophile_hugs — 2010-08-01T15:27:31Z
This program compiles with no errors with dmd 2.047:
int[1][3] a1 = [1, 2, 3];
void main() {
int[1][3] a2 = [1, 2, 3];
}
But those array literals are wrong. This is the correct program:
int[1][3] a1 = [[1], [2], [3]];
void main() {
int[1][3] a2 = [[1], [2], [3]];
}
A sloppy syntax is bad because it *always* offers space for bugs, like this one, dmd compiles this program with no errors (note the missing comma):
int[1][3] a = [[1] [0], [2]];
void main() {}
Now a contains [1, 2, 0], a silent bug.
This situation is partially caused by bug 3849
Comment #1 by andrej.mitrovich — 2012-10-22T16:00:17Z
Do you by any chance have a somewhat elaborate set of test-cases that cover many types of arrays which should and shouldn't compile? It would help to make solid test-cases.
Otherwise I'll write them myself, no problem.
Comment #2 by bearophile_hugs — 2012-10-22T16:26:08Z
(In reply to comment #1)
> Do you by any chance have a somewhat elaborate set of test-cases that cover
> many types of arrays which should and shouldn't compile?
I don't, sorry. Currently finding such test cases is a laborious manual work. There is no fuzzy testing framework for D, as ones used on the certified C compiler.
(In reply to comment #0)
> This program compiles with no errors with dmd 2.047:
>
> int[1][3] a1 = [1, 2, 3];
> void main() {
> int[1][3] a2 = [1, 2, 3];
> }
>
> But those array literals are wrong. This is the correct program:
>
> int[1][3] a1 = [[1], [2], [3]];
> void main() {
> int[1][3] a2 = [[1], [2], [3]];
> }
I think this is not a bad program.
> int[1][3] a1 = [1, 2, 3];
is same as:
int[1][3] a1 = void;
a1[0][] = 1; // fill all elements by 1
a1[1][] = 2; // fill all elements by 2
a1[2][] = 3; // fill all elements by 3
Then a1 is initialized by [[1], [2], [3]].
And it is consistent with:
int[3] sa = 1; // sa is initialized to [1, 1, 1]
----
> A sloppy syntax is bad because it *always* offers space for bugs, like this
> one, dmd compiles this program with no errors (note the missing comma):
>
> int[1][3] a = [[1] [0], [2]];
> void main() {}
[1][0] is an expression which indexing array literal, and evaluated to 1.
It's equivalent to: [1,2,3][0] == 1
> Now a contains [1, 2, 0], a silent bug.
Now a is initialized by [1, [2]], and is same as:
int[1][3] a = void;
a[0][] = 1;
a[1] = [2];
a[2][] = 0; // == int.init
After all, a == [1, 2, 0]. There is no bug.
Comment #5 by andrej.mitrovich — 2012-11-15T00:56:56Z
Comment #6 by bearophile_hugs — 2013-03-11T19:44:12Z
(In reply to comment #4)
Sorry for the very delayed answer.
> > A sloppy syntax is bad because it *always* offers space for bugs, like this
> > one, dmd compiles this program with no errors (note the missing comma):
> >
> > int[1][3] a = [[1] [0], [2]];
> > void main() {}
>
> [1][0] is an expression which indexing array literal, and evaluated to 1.
> It's equivalent to: [1,2,3][0] == 1
>
> > Now a contains [1, 2, 0], a silent bug.
>
> Now a is initialized by [1, [2]], and is same as:
> int[1][3] a = void;
> a[0][] = 1;
> a[1] = [2];
> a[2][] = 0; // == int.init
>
> After all, a == [1, 2, 0]. There is no bug.
In my opinion that's probably a bug in user code. I doubt the user meant to write that. Most probably the user meant to write this, but missed a comma after the first sub-array:
int[1][3] a = [[1], [0], [2]];
void main() {}
But this is an uncommon situation, so I think it's not worth thinking too much about it.
What follows is more important:
> I think this is not a bad program.
> > int[1][3] a1 = [1, 2, 3];
> is same as:
>
> int[1][3] a1 = void;
> a1[0][] = 1; // fill all elements by 1
> a1[1][] = 2; // fill all elements by 2
> a1[2][] = 3; // fill all elements by 3
>
> Then a1 is initialized by [[1], [2], [3]].
>
> And it is consistent with:
> int[3] sa = 1; // sa is initialized to [1, 1, 1]
Today this syntax compiles:
void main() {
int[1][3] a2;
a2[0][] = 1;
a2[1][] = 2;
a2[2][] = 3;
}
This used to compile fine, but today it gives warnings (and this is good):
void main() {
int[1][3] a3;
a3[0] = 1;
a3[1] = 2;
a3[2] = 3;
}
temp.d(3): Warning: explicit element-wise assignment (a3[cast(uint)0])[] = 1 is better than a3[cast(uint)0] = 1
temp.d(4): Warning: explicit element-wise assignment (a3[cast(uint)1])[] = 2 is better than a3[cast(uint)1] = 2
temp.d(5): Warning: explicit element-wise assignment (a3[cast(uint)2])[] = 3 is better than a3[cast(uint)2] = 3
Currently both of the following forms are accepted:
void main() {
int[1][3] a1 = [[1], [2], [3]];
int[1][3] a2 = [1, 2, 3];
}
Generally I trust your good judgement Hara, but if we are going to deprecate the assignment of array slices without using [], then I don't know if the idea of allowing both of those syntaxes is a good idea...
Comment #7 by samjnaa — 2013-05-31T10:33:43Z
(In reply to comment #4)
>
> I think this is not a bad program.
> > int[1][3] a1 = [1, 2, 3];
> is same as:
>
> int[1][3] a1 = void;
> a1[0][] = 1; // fill all elements by 1
> a1[1][] = 2; // fill all elements by 2
> a1[2][] = 3; // fill all elements by 3
>
> Then a1 is initialized by [[1], [2], [3]].
>
> And it is consistent with:
> int[3] sa = 1; // sa is initialized to [1, 1, 1]
FWIW I agree with bearophile here. In the case of having a single value on the RHS it is easy (?) to construe how int[3] a = 1 (or even maybe int[3][3] a = 1) would initialize all the elements, but when you specify an array literal on the RHS, I think it should have the same shape as the array specified in the type on the LHS to avoid hard-to-find bugs.
Comment #8 by robert.schadek — 2024-12-13T17:52:44Z