Strange copying of a constant array of structures

Vindex tech.vindex at gmail.com
Fri Jun 14 08:03:47 UTC 2024


Last night I encountered some strange behavior of the dup 
function.

```
import std.stdio;

struct S {
     int x;
     int y;
     int[] arr;
     this(ref return scope const S rhs) {
         writeln("copy ctor");
         this.x = rhs.x;
         this.y = rhs.y;
         this.arr = rhs.arr.dup;
     }
}

void main() {
     const S[] array = [S(0, 0), S(1, 2)];
     S[] copy = array.dup;  // error
}
```

We have an issue:
```
Error: none of the overloads of template `object.dup` are 
callable using argument types `!()(const(S[]))`
```

But(!) if we remove the dynamic array field from the structure, 
everything works.


I decided to get around the problem by writing my own function to 
copy arrays:

```
T[] copyArray(T)(const T[] arr) {
     T[] copy = new T[arr.length];
     for (size_t i = 0; i < arr.length; i++) {
         copy[i] = arr[i];  // error
     }
     return copy;
}

void main() {
     const S[] array = [S(0, 0), S(1, 2)];
     S[] copy = copyArray(array);
}
```

Nice, simple function, but it doesn't compile on the assignment 
line:
```
Error: cannot implicitly convert expression `arr[i]` of type 
`const(S)` to `S`
```
(The feature is the same: if we remove the dynamic array field 
from the structure, everything works.)

An additional variable solution worked:

```
T[] copyArray(T)(const T[] arr) {
     T[] copy = new T[arr.length];
     for (size_t i = 0; i < arr.length; i++) {
         T elem = arr[i];  // copy ctor is called
         copy[i] = elem;  // copy ctor isn't called!
     }
     return copy;
}
```

I feel that I do not understand something, please explain what is 
the problem of constant structures with reference fields?

And why is the copy constructor only called once in the last 
example? Optimization?



More information about the Digitalmars-d mailing list