1

I have a problem with pointer types. GCC compiler throws a warning like this:

416:31: warning: passing argument 1 of 'locateInHWNDArray' from 
    incompatible pointer type [-Wincompatible-pointer-types]
         locateInHWNDArray(hWndLWTxt, (HWND)lParam, &x, &y);
                           ^
foodplaner.c:76:6: note: expected 'struct HWND__ ***'
but argument is of type 'struct HWND__ * (*)[4]'
void locateInHWNDArray(HWND **array, HWND el, int *x, int *y);
     ^

The function signature looks like this:

void locateInHWNDArray(HWND **array, HWND el, int *x, int *y)

and the call is the following

locateInHWNDArray(hWndTWTxt, (HWND)lParam, &x, &y);

with hWndTwTxt declared as

HWND hWndTWTxt[7][4];

I assume this has to do something with having it declared with a certain size, but I have no idea what the compiler exactly wants.

Doopy
  • 636
  • 8
  • 21

3 Answers3

2

HWND **array expects an array of pointers, not a 2D array. You can declare it as:

HWND* hWndTWTxt[n]

You must then create each pointer in the array individually.

See this answer for more explanation:

https://stackoverflow.com/a/16724679/6726446

Community
  • 1
  • 1
js441
  • 1,134
  • 8
  • 16
2

The problem is that a two-dimensional array and a pointer to a pointer are not the same thing.

foodplaner.c:76:6: note: expected 'struct HWND__ ***' but argument is of type 'struct HWND__ * (*)[4]'

The first part of this error message (before the "but") simply means that HWND is equivalent to a HWND__ * (where HWND__ is a type defined in a header file included in your project).

The second part of the error message (after the "but") is telling you that hWndTwTxt is being passed as a pointer to an array of 4 HWND__ *. This is consistent - a 2D array of dimension [7][4] is passed as a pointer to an array of 4 elements.

In combination, the error message is telling you that a 2D array cannot be converted into a pointer to a pointer.

Assuming your function needs to be passed something that resembles a 2D array then you either need specify your function as

void locateInHWNDArray(HWND array[7][4], HWND el, int *x, int *y)

or as

void locateInHWNDArray(HWND (*array)[4], HWND el, int *x, int *y)

Either of these rely on the second (right-most) dimension (i.e. 4) being known at compile time. Either way, the function must use valid array indices (i.e. when doing something with array[i][j], i must be between 0 and 7 and j must be between 0 and 4).

If you really want to pass a HWND ** (i.e. not changing the function argument types) then you will need to do something like this

HWND **temp;
int i, j;
temp = malloc(7*sizeof(*temp));
for (i = 0; i < 7; ++i)
{
    temp[i] = malloc(4*sizeof(*temp[i]));
    for (j = 0; j < 4; ++j)
        temp[i][j] = hWndTWText[i][j];
}

locateInHWNDArray(temp, (HWND)lParam, &x, &y);

/* copy from temp back to `hWndTWText` if the function modifies elements */

for (int i = 0; i < 7; ++i)
    free(temp[i]);
free(temp);

The function still needs to ensure indices are valid (which, if the array dimension are not fixed at compile time, means they must be passed, somehow, to the function - for example, as additional arguments).

Peter
  • 35,646
  • 4
  • 32
  • 74
0

Here is what you need.

In short, you need to pass the number of dimensions as pointers, but since you have a static array (and a static 2D array requires that second level of pointers be const pointer to static array), this will work:

void locateInHWNDArray(HWND array[7][4], HWND el, int *x, int *y)

Or use any of the ways listed in the linked answer.

Community
  • 1
  • 1
smrdo_prdo
  • 234
  • 2
  • 12