## digitalmars.D.learn - Array Operations and type inference

• simendsjo (88/88) Aug 07 2010 I'm new to D2, so please.. :)
• Mafi (11/91) Aug 07 2010 Hi,
• Mafi (20/93) Aug 07 2010 Hey, here Mafi again,
• Don (3/18) Aug 07 2010 That is bug 4578, which has been fixed, and will be in the next compiler...
• bearophile (16/75) Aug 08 2010 Sorry for the late answer, I am quite busy now. Mafi has already answere...
• bearophile (7/20) Aug 08 2010 Good, there is no need to file it then.
• simendsjo (4/5) Aug 08 2010 (...)
simendsjo <simen.endsjo pandavre.com> writes:
```I'm new to D2, so please.. :)

The spec on Array Operations,
http://www.digitalmars.com/d/2./arrays.html says:
"""A vector operation is indicated by the slice operator appearing as
the lvalue of an =, +=, -=, *=, /=, %=, ^=, &= or |= operator."""

The following tests works fine as I expected:

{
double[3] a = [1,1,1];
double[3] b;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

{
double[3] a = [1,1,1];
auto b = a;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

But from here on I'm having problems...

{
double[] a = [1,1,1];
double[] b;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // fails as b.length == 0.. Should the compiler
say something?
}

{
double[] a = [1,1,1];
double[] b;
b.length = a.length;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // Now it's fine
}

{
double[3] a = [1,1,1];
double[3] b = a[] + 3; // works although lvalue isn't a slice. Static
arrays? Because it's an initial value?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

{
double[3] a = [1,1,1];
auto b = a;
b = a[] + 3; // And so does this.. Something to do with static arrays?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

{ // Like the previous example, but with dynamic arrays..
double[] a = [1,1,1];
auto b = a;
assert(a is b);
b = a[] + 3;
assert(a == [1,1,1]);
//writeln(b); // access violation. Because of dynamic arrays?
}

{ // Like above, but using slicing like the spec says.. Works fine
double[] a = [1,1,1];
auto b = a;
assert(a is b);
writeln(typeof(b).stringof); // double[]
b[] = a[] + 3;
assert(a == [4,4,4]); // a also changed. I expected this
assert(b == [4,4,4]);
}

{
double[3] a = [1,1,1];
auto b = a[] + 3; // What happens here?
writeln(typeof(b).stringof); // double[]
assert(b.length == 3);
assert(b.capacity == 0);
//writeln(b); // access violation
}

{ // Same as above?
double[3] a = [1,1,1];
//writeln(a[] + 3); // access violation
}

```
Aug 07 2010
Mafi <mafi example.org> writes:
```Am 07.08.2010 14:10, schrieb simendsjo:
I'm new to D2, so please.. :)

The spec on Array Operations,
http://www.digitalmars.com/d/2./arrays.html says:
"""A vector operation is indicated by the slice operator appearing as
the lvalue of an =, +=, -=, *=, /=, %=, ^=, &= or |= operator."""

The following tests works fine as I expected:

{
double[3] a = [1,1,1];
double[3] b;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

{
double[3] a = [1,1,1];
auto b = a;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

But from here on I'm having problems...

{
double[] a = [1,1,1];
double[] b;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // fails as b.length == 0.. Should the compiler
say something?
}

{
double[] a = [1,1,1];
double[] b;
b.length = a.length;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // Now it's fine
}

{
double[3] a = [1,1,1];
double[3] b = a[] + 3; // works although lvalue isn't a slice. Static
arrays? Because it's an initial value?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

{
double[3] a = [1,1,1];
auto b = a;
b = a[] + 3; // And so does this.. Something to do with static arrays?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

{ // Like the previous example, but with dynamic arrays..
double[] a = [1,1,1];
auto b = a;
assert(a is b);
b = a[] + 3;
assert(a == [1,1,1]);
//writeln(b); // access violation. Because of dynamic arrays?
}

{ // Like above, but using slicing like the spec says.. Works fine
double[] a = [1,1,1];
auto b = a;
assert(a is b);
writeln(typeof(b).stringof); // double[]
b[] = a[] + 3;
assert(a == [4,4,4]); // a also changed. I expected this
assert(b == [4,4,4]);
}

{
double[3] a = [1,1,1];
auto b = a[] + 3; // What happens here?
writeln(typeof(b).stringof); // double[]
assert(b.length == 3);
assert(b.capacity == 0);
//writeln(b); // access violation
}

{ // Same as above?
double[3] a = [1,1,1];
//writeln(a[] + 3); // access violation
}

Hi,
I don't the answer to all of your problems but what I can say you is:
* D-Arrays are references to structs which point to the data
* An arrayvariable on the left-hand-side of an assignment sets the
reference of this variable. (no copy!)
* An array slice is mostly the same as the array variable itself but if
it's on the left-hand-side of an assignment, the data is copied from the
right-hand-side.

So for example your third example can't work because b is null and so
there's no place you can copy the data to.
```
Aug 07 2010
Mafi <mafi example.org> writes:
```Hey, here Mafi again,

Am 07.08.2010 14:10, schrieb simendsjo:
{
double[3] a = [1,1,1];
double[3] b;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

{
double[3] a = [1,1,1];
auto b = a;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

But from here on I'm having problems...

{
double[] a = [1,1,1];
double[] b;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // fails as b.length == 0.. Should the compiler say
something?
}

As I said in my first post b is null. Now the third line tries to _copy_
that the compiler complains would be difficult but in my opinion it
should result in an runtime error.
{
double[] a = [1,1,1];
double[] b;
b.length = a.length;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // Now it's fine
}

With setting b's length you (re)allocate(1) memory for the array so now
there's place to copy to.

{
double[3] a = [1,1,1];
double[3] b = a[] + 3; // works although lvalue isn't a slice. Static
arrays? Because it's an initial value?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

You simply intialize the fixed-size array with a dynamic one. I'm not
sure but I think the data is copied out of the dynamic temporary array to b.
{
double[3] a = [1,1,1];
auto b = a;
b = a[] + 3; // And so does this.. Something to do with static arrays?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

In the second line you initialize to a and then do the same as above.
Note: In D fixed-size arrays are value types.
{ // Like the previous example, but with dynamic arrays..
double[] a = [1,1,1];
auto b = a;
assert(a is b);
b = a[] + 3;
assert(a == [1,1,1]);
//writeln(b); // access violation. Because of dynamic arrays?
}

I have no idea. Maybe the array generated by the vector addition is kind
of temporary and you have to copy. But it could also be a bug.
Vector-operations are still quite buggy.
{ // Like above, but using slicing like the spec says.. Works fine
double[] a = [1,1,1];
auto b = a;
assert(a is b);
writeln(typeof(b).stringof); // double[]
b[] = a[] + 3;
assert(a == [4,4,4]); // a also changed. I expected this
assert(b == [4,4,4]);
}

Now you are copying to b(which references the same struct as a).
{
double[3] a = [1,1,1];
auto b = a[] + 3; // What happens here?
writeln(typeof(b).stringof); // double[]
assert(b.length == 3);
assert(b.capacity == 0);
//writeln(b); // access violation
}

It's the same as to steps before this(my  english isn't ver good ;))
{ // Same as above?

I think it is.
double[3] a = [1,1,1];
//writeln(a[] + 3); // access violation
}

(1)It's normally for reallocation when you need more space.
```
Aug 07 2010
Don <nospam nospam.com> writes:
```Mafi wrote:
Hey, here Mafi again,

Am 07.08.2010 14:10, schrieb simendsjo:

{ // Like the previous example, but with dynamic arrays..
double[] a = [1,1,1];
auto b = a;
assert(a is b);
b = a[] + 3;
assert(a == [1,1,1]);
//writeln(b); // access violation. Because of dynamic arrays?
}

I have no idea. Maybe the array generated by the vector addition is kind
of temporary and you have to copy. But it could also be a bug.
Vector-operations are still quite buggy.

That is bug 4578, which has been fixed, and will be in the next compiler
release.
```
Aug 07 2010
bearophile <bearophileHUGS lycos.com> writes:
```Sorry for the late answer, I am quite busy now. Mafi has already answered, I
will probably repeat some things already said.

simendsjo:

Array ops currently have many bugs, they are fragile asm glass things, so when
you use them you have to be kind, if you misuse them a bit things crash and
burn :-) With time bugs will be removed. Currently D array ops are not
efficient for small arrays.

{
double[] a = [1,1,1];
double[] b;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // fails as b.length == 0.. Should the compiler
say something?
}

That is wrong code, because array operations don't allocate new memory.
The compiler (or runtime, because those are dynamic arrays) must complain here,
but here it doesn't yet, and there's already a bug report on this.

{
double[] a = [1,1,1];
double[] b;
b.length = a.length;
b[] = a[] + 3;
assert(a == [1,1,1]);
assert(b == [4,4,4]); // Now it's fine
}

This is fine because in D the length attribute can also be written, this
changes the array length, so there's space for the data to be written.

{
double[3] a = [1,1,1];
double[3] b = a[] + 3; // works although lvalue isn't a slice. Static
arrays? Because it's an initial value?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

This works because of another bug in the compiler (it accepts some array ops
even without the []), I have written a bug report on this lot of time ago.
Walter has said this bug will be fixed.

{
double[3] a = [1,1,1];
auto b = a;
b = a[] + 3; // And so does this.. Something to do with static arrays?
assert(a == [1,1,1]);
assert(b == [4,4,4]);
}

Same compiler bug as above, that allows such sloppiness. Also b is a static
array so the operation "auto b = a;" copies 3 values on the stack, so this is
partially correct code.

{ // Like the previous example, but with dynamic arrays..
double[] a = [1,1,1];
auto b = a;
assert(a is b);
b = a[] + 3;
assert(a == [1,1,1]);
//writeln(b); // access violation. Because of dynamic arrays?
}

I don't know, seems a bit messy. I will add it to bugzilla, despite it's
partially wrong code.

{ // Like above, but using slicing like the spec says.. Works fine
double[] a = [1,1,1];
auto b = a;
assert(a is b);
writeln(typeof(b).stringof); // double[]
b[] = a[] + 3;
assert(a == [4,4,4]); // a also changed. I expected this
assert(b == [4,4,4]);
}

This is OK.

{
double[3] a = [1,1,1];
auto b = a[] + 3; // What happens here?
writeln(typeof(b).stringof); // double[]
assert(b.length == 3);
assert(b.capacity == 0);
//writeln(b); // access violation
}

In the second line you take a full slice of a static array, in practice
defining a dynamic array with the same contents (no data copy).
The code is wrong because in the second line there is no [].
The runtime is buggy because the second line assigns to an empty array. I guess
I have to add this too to bugzilla, plus another case.

{ // Same as above?
double[3] a = [1,1,1];
//writeln(a[] + 3); // access violation
}

This is not allowed by the current design of array operations. I'd like the
compiler to catch this erroneus usage at compile time. I think I have put this
in bugzilla lot of time ago.

Bye,
bearophile
```
Aug 08 2010
bearophile <bearophileHUGS lycos.com> writes:
```Don:
That is bug 4578, which has been fixed, and will be in the next compiler
release.

Good, there is no need to file it then.

simendsjo post shows two more cases, this is the first:

{
double[3] a = [1,1,1];
auto b = a[] + 3; // What happens here?
writeln(typeof(b).stringof); // double[]
assert(b.length == 3);
assert(b.capacity == 0);
//writeln(b); // access violation
}

The runtime has to catch the assignment bug in the line annotated with "What
happens here?". I think there is already a bug in bugzilla for this so I will

{ // Same as above?
double[3] a = [1,1,1];
//writeln(a[] + 3); // access violation
}

I don't remember if this case is already in bugzilla, and I don't know if the
compiler can catch it. I add it to bug 3817 because I am not sure.

Bye,
bearophile
```
Aug 08 2010
simendsjo <simen.endsjo pandavre.com> writes:
```On 07.08.2010 14:10, simendsjo wrote:
I'm new to D2, so please.. :)

(...)

Thanks for all answers. Seems array operations is a bit buggy, so I'll
rather look more into them at a later date.
```
Aug 08 2010