1

I wrote the piece of code below but when I tried to return some two-dimensional array, it throws the following error.

    int (* function (int input[2][2]) ) [2][2]{

        return input;

    }

gcc compiler error message

from trial and error, I understand that when I change the function declaration to int (* function (args) ) [2] {...} it works like a charm, but why??? I don't understand. How C++ actually sees arrays? How these return declarations int (* function () )[n][m] actually works? What happens when I add another * to function declaration int *(* function () )[n][m] ??

My source for finding the solution to this problem was this but I just copied some code and understood almost 0% of it.

It'll be nice if someone could explain to me how these work, and it would mean a world to me if you can suggest a good reading source for understanding these somewhat advanced notions in C++.

ARK1375
  • 790
  • 3
  • 19
  • You have different types for the parameter and return type, there is an extra `*` in the return type – M.M May 17 '20 at 22:02
  • @M.M So I've figured, but I don't know how these pointer return types work overall. – ARK1375 May 17 '20 at 22:05
  • 2
    "from trial and error..." - Don't learn C++ from trial and error. There are just too many incorrect things that can appear to work and you won't really understand things. Get a [good book](https://stackoverflow.com/q/388242/9254539). As far as I know, you simply can't return a plain array in C++. – eesiraed May 17 '20 at 22:06

1 Answers1

1

In this function declaration

int (* function (int input[2][2]) ) [2][2];

the argument of the array type is implicitly adjusted by the compiler to pointer to the array element type. That is for example these function declarations

int (* function (int input[2][2]) ) [2][2];

int (* function (int input[100][2]) ) [2][2];

int (* function (int input[][2]) ) [2][2];

declares the same one function that is equivalent to

int (* function (int ( *input )[2]) ) [2][2];

So within the function the variable input has the pointer type int ( * )[2]. This pointer you are returning from the function

    return input;

So the function return type also must be int ( * )[2]. That means that the function must be declared like

int (* function (int input[2][2]) ) [2];

You could declare the parameter as having a referenced type. In this case you may return reference to the array.

int ( & function (int ( &input )[2][2]) )[2] [2];

Array types may not be used as the return type of function.

As for this declaration

int *(* function () )[n][m];

where n and m shall be constant expressions then the function returns pointer of the type int * ( * )[n][m]. For example the function can use an array name declared within the function with the static storage duration something in a return statement like

static int * a[k][n][m];

//

return a;

So if you have an array as for example

T a[N1][N2][N3];

where T is some type and N1, N2, and N3 its sizes then this declaration you may rewrite like

T ( a[N1] )[N2][N3];

Used in expressions the array (with rare exceptions) is converted to pointer to its first element. To declare such a pointer substitute the record in the parentheses to pointer like

T ( *p )[N2][N3] = a;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335