0

If I create a function with function parameter

void test(arr[][])
{
...
}

then I get the following error

error: array type has incomplete element type 

but the following is fine apparently

void test(arr[][2])
{
...
}

Why does the compiler need to know the size of the second dimension of my multidimensional array? If arr[i][j] can deduce i elements automatically it should be able to deduce j elements as well right?

I am looking for an explanation rather than the solution as posted here

array type has incomplete element type

user395980
  • 356
  • 1
  • 8
  • C 2018 6.7.6.2 1 says of array declarators “The element type shall not be an incomplete or function type.” The element type of `arr[]` is incomplete because it is an array of some number of elements, and the number is not known. – Eric Postpischil Mar 22 '20 at 13:58
  • **The compiler *cannot* deduce `i` (the first index).** All the function `test()` is seeing is *a bare pointer.* Nothing in C prevents you to access `arr[123456789]` in `test()`, usually with fatal consequences. – Peter - Reinstate Monica Mar 22 '20 at 14:10
  • @tevemadar: The rule is at least two decades old; it appears in the 1999 C standard. Speculation about what “might” be the cause of the rule has no bearing on the fact that it is the rule and is the reason the compiler emits the diagnostic. Furthermore, it is the only reason, as the fact that `int (*arr)[]` is accepted proves it is technically possible for `int arr[][]` to be accepted. There are times when the former is useful. Further, there is no reason an answer cannot inform about both the rule and the benefit of providing the size, and an answer without the correct rule is deficient. – Eric Postpischil Mar 23 '20 at 11:31

1 Answers1

1

You're asking the compiler to give you data from row i and column j.

It needs to skip over rows 0...i-1. How many ints are in each row, in order to do that? Hmm... you need to tell it (2 in your example).

Once on the correct row, it can count j ints further to find the data you want.

Remember in RAM, the array isn't organized two-dimensionally. It's just a long long line of ints. To reach the section of the line holding row i, it has to skip over many in that line - and it needs to be able to compute how many.

One could imagine a queue of people waiting to fill a cinema (each row of seats in this cinema has the same number of seats). The people will fill row 1, then row 2, then row 3, ... You're asked to find, in the queue, the first person who will sit in row 3, to give them free popcorn. How many people will you count past? You'll definitely need to know how many people in each row, won't you? And yet it's irrelevant how many rows the cinema has, you don't need that information at all!

(You don't have to specify how many in the other element, because C arrays aren't bound like that, they have no upper bound; the compiler has enough info here to access row 0 or row 1,000,000, and will happily attempt either for you. It'll be up to you to pass in a valid pointer referring to that many rows.)

Graham Perks
  • 23,007
  • 8
  • 61
  • 83
  • Not quite; the code shown does not contain any place where it is “asking the compiler to give you data from row i and column j.” All we see is the parameter declaration, and the compiler gives an error message there, not where the parameter is used. In fact, we can declare a similar parameter, `int (*arr)[]`, without error, and `int arr[][]` is equivalent to `int (*arr)[]` after the automatic adjustment that the C standard specifies. So there is a different reason for the error message, and that is the C standard has a rule that the element type for an array declarator must be a complete type. – Eric Postpischil Mar 22 '20 at 13:53