How to pass in reference a fixed array in parameter

Quirin Schroll qs.il.paperinik at gmail.com
Thu Jun 6 14:10:40 UTC 2024


On Tuesday, 4 June 2024 at 12:22:23 UTC, Eric P626 wrote:
> I am currently trying to learn how to program in D. I thought 
> that I could start by trying some maze generation algorithms. I 
> have a maze stored as 2D array of structure defined as follow 
> which keep tracks of wall positions:
>
> ~~~
> struct s_cell
> {
>    bool north = true;
>    bool east = true;
>    bool south = true;
>    bool west = true;
> }
> ~~~
>
> I try to create a 2D array of fixed length and pass it in 
> parameter as a reference. Normally, in C, I would have used a 
> pointer as parameter, and pass the address of the array. Here, 
> I thought it would have been easier just to pass a slice of the 
> array, since a slice is a reference to the original array. So I 
> wrote the signature like this:
>
> ~~~
> void main()
> {  writeln("Maze generation demo");
>
>    s_cell [5][5] maze;
>    print_maze (maze);
>
> }
>
> void print_maze ( s_cell [][] maze )
> {
> }
> ~~~
>
> My idea is that print_maze use a slice of what ever is sent in 
> parameter. Unfortunately, I get the following error message:
>
> ~~~
> Error: function `mprmaze.print_maze(s_cell[][] maze)` is not 
> callable using argument types `(s_cell[5][5])`
>   cannot pass argument `maze` of type `s_cell[5][5]` to 
> parameter `s_cell[][] maze`
> ~~~
>
> I tried to find a solution on the internet, but could not find 
> anything, I stumble a lot on threads about Go or Rust language 
> even if I specify "d language" in my search.
>
> Else is there other ways to pass an array as reference using 
> parameter modifiers like: ref,in,out ...
>
> Else, can it be done the C way using pointers?
>
> Thank you.

First things first, put `@safe:` on the top of the file or put 
`@safe` at the end of every function declarator. It makes 
anything that could be undefined behavior an error:
```d
void main() @safe
{
     writeln("Maze generation demo");

     s_cell [5][5] maze;
     print_maze (maze);

}

// change to: ( const ref s_cell [5][5] maze )
void print_maze ( s_cell [][] maze ) @safe
{
}
```

A `T[]` is a pointer–length pair, aka. a slice. A `T[n]` is a 
block of `n` values of type `T`. Assuming you know a thing or two 
about C, a `T[n]` converts to a `T[]` like an `int` converts to a 
`long`: It’s lossless and safe, but not pointer compatible.

For the same reason an `int*` can’t convert to a `long*`, a 
`T[m][n]` can’t convert to a `T[][]`.

Also, if you’re new, be aware some people call slices “dynamic 
arrays,” which is really misleading sometimes.

* If a function writes a maze, pass the maze by `ref`. Note that 
`ref` is not part of the parameter’s type (as in C++), but a 
property of the parameter akin to its type.
* If a function only reads a maze, pass the maze by `const ref`; 
or `in` using the command-line option `-preview=in` which: allows 
rvalues and doesn’t bind by reference if the object bound is 
small and trivial to copy.


More information about the Digitalmars-d-learn mailing list