Passing a multidimensional array to work without extreme size with a pointer to an incomplete array type

From what I remember, arrays are always passed as pointers. For example, an ad:

void foo(int array[2][5]);

means for the compiler the same as:

void foo(int (*array)[5]);

You can say that both of these forms are equivalent. Now, I wonder why this is allowed to declare it as:

void foo(int (*array)[]);

not like:

void foo(int array[][]);

Take an example:

#include <stdio.h>

void foo(int (*p)[3]);
void bar(int (*p)[]);

int main(void)
{
    int a[2][3] = {{1, 2, 3}, {4, 5, 6}};

    foo(a);
    bar(a);

    return 0;
}

// The same as int p[][3] or int p[N][3] where N is a constant expression
void foo(int (*p)[3]) 
{

}

// Would it the same as int p[][] or int p[N][] (by analogy)?
void bar(int (*p)[])
{

}

It compiles fine and without warning, but if I change the declaration barto:

void bar(int p[][]);

then this is a mistake.

Why does C allow such an "obscure" way to pass an array?

+4
source share
3 answers

C "" , , , .

, - bar, :

void bar(int (*p)[])
{
    printf("%d\n", p[1][1]);
}

% gcc -Wall t.c
t.c: In function β€˜bar’:
t.c:23:5: error: invalid use of array with unspecified bounds
     printf("%d\n", p[1][1]);
     ^

, p , - - , ( ), , , undefined .

+2

, , , , poitners, , p[][] , , .

, int p[][], , p[0] p[1], int (*p)[] , - .

, .

+5

, , ; , . , , , , , , , .

C . , . , :

int a[4][5];

:

  [0]                 |[1]                |[2]                |[3]
  +-------------------|-------------------|-------------------|-------------------+
a |   |   |   |   |   |   |   |   |   |   |   |   | X |   |   |   |   |   |   |   |
  +-------------------|-------------------|-------------------|-------------------+
    0   1   2   3   4 | 0   1   2   3   4 | 0   1   2   3   4 | 0   1   2   3   4 |

[2][2], ():

  • int ,
  • ,
  • int ,
  • ;

*(a + (2 * 5 * sizeof(int)) + (2 * sizeof(int))), *(a + 12*sizeof(int)), .

, , . - ( ) , , .

+5

Source: https://habr.com/ru/post/1598096/


All Articles