Copying array with const correctness

Steven Schveighoffer schveiguy at gmail.com
Wed Oct 8 02:58:15 UTC 2025


On Tuesday, 7 October 2025 at 18:43:18 UTC, Vindex9 wrote:

> What am I doing wrong?
> I want a safe copy: `const string[][] -> string[][]`.

I think the approach should be, make a copy, then cast the copy, 
recurse if it's a nested array.

What you are likely running into is that D automatically strips 
the top-level const from a templated array.

That is:

```d
void foo(T)(T[] arr) {
     pragma(msg, "in foo: ", typeof(arr)); // const(int)[]
}

void main()
{
    const int[] arr;
    pragma(msg, "in main: ", typeof(arr)); // const(int[])
    foo(arr);
}
```

On top of that, you are adding `const` to the incoming type, 
which can be problematic.

What I'd recommend is `inout` instead. This will unwrap to the 
original type but still keep you from modifying the original 
(like const).

My attempt:

```d
import std.traits;

inout(T)[] copyArray(T)(inout(T)[] arr) {
     alias M = Unqual!T;
     M[] result;
     result.length = arr.length;
     foreach(i, ref v; result) {
         static if(is(T == U[], U)) // it's an array of arrays
             v = cast(M)copyArray(arr[i]);
         else
             v = cast(M)arr[i];
     }

     return cast(typeof(return))result;
}

void main()
{
     import std.stdio;
   	const string[][] arr = [["ABC", "DEF"], ["GHI", "JKL"]];
     writeln(typeid(arr));  // 
const(const(const(immutable(char)[])[])[])
     const res = copyArray(arr); // note the const here, but still 
typesafe without!
     writeln(typeid(res));  // 
const(const(const(immutable(char)[])[])[])
}
```

-Steve


More information about the Digitalmars-d-learn mailing list