1

While declaring a 2-D array in C, I see that the following ways of declarations are valid:

int a[2][3] = {1,2,3,4,5,6}
int a[2][3] = {{1,2,3}, {4,5,6}}
int a[][3] = {1,2,3,4,5,6}

But, the following way of array declaration is invalid in C:

int a[2][] = {1,2,3,4,5,6}

Why is it mandatory to mention the number of columns, regardless of mentioning the number of rows while declaring a 2-D array in C?

vagdevi k
  • 1,478
  • 9
  • 25
  • Does this answer your question? [Why is dimension range of higher dimensions in multi-dimensional array required?](https://stackoverflow.com/questions/35289985/why-is-dimension-range-of-higher-dimensions-in-multi-dimensional-array-required) – Bob__ Jun 19 '21 at 13:34

2 Answers2

5

There are multiple possible answers, but most start from the fact that C n-dimensional arrays are 1-dimensional arrays of (n-1)-dimensional arrays. From here, we can go several directions, such as

  • the declared type of an array's elements must be a complete type, and array types having an unspecified dimension are not complete types.

  • that's closely related to the fact that C's array indexing and the equivalent pointer arithmetic depend on knowing the size of the elements of the array / pointed-to type, and (being an incomplete type) the size of an array type with an unspecified dimension is not known.

  • Coming from another direction, a declaration such as your example ...

    int a[2][] = {1,2,3,4,5,6}
    

    ... does not suffice to establish the second dimension of the array. That same initializer would be valid in all of these, among unboundedly-many others:

    int a3[2][3] = {1,2,3,4,5,6};    // equivalent to {{1,2,3},{4,5,6}}
    int a4[2][4] = {1,2,3,4,5,6};    // equivalent to {{1,2,3,4},{5,6}}
    int a5[2][5] = {1,2,3,4,5,6};    // equivalent to {{1,2,3,4,5},{6}}
    int a6[2][6]   = {1,2,3,4,5,6};  // equivalent to {{1,2,3,4,5,6}}
    int a10[2][10] = {1,2,3,4,5,6};  // equivalent to {{1,2,3,4,5,6}}
    

    Note in particular that C does not require an explicit initializer element for every element in any array being initialized.

The ultimate answer, though, is simply that the language designers chose that it should be as it is. Their choice seems logical and internally consistent to me, but that does not mean that they couldn't have chosen differently. Ultimately, there is no other "why?" that matters.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
3

To well answer this question, we first need to get ourselves familiarized with two concepts: row-major implementation and column-major implementation.

In Row-Major Implementation, the elements of a row of an array are placed next to those of the previous row elements. All row elements are placed in contiguous memory addresses. Whereas in Column-Major Implementation, the column-wise elements are placed next to each other in contiguous memory allocations.

For more explanation: https://en.wikipedia.org/wiki/Row-_and_column-major_order

enter image description here

Now coming back, C/C++ language is based on Row-Major implementation. Thus, even if we don't give the number of rows while declaring an array, the number of columns provided during the declaration would be sufficient for the compiler to decide the row to which an element should belong to.

For example, in the following way of declaration and initialization:

int a[][3] = {1,2,3,4,5,6}

Though the number of rows is not mentioned, the number of columns provided would help the compiler decide that the elements 1,2,3 should belong to the first row of the matrix, and 4,5,6 elements should belong to the second row, since each row should only contain 3columns. So this type of declaration and initialization is valid.

On the other hand, in the following example,

int a[2][] = {1,2,3,4,5,6}

It is only given that there should be 2 rows. But since C a is row-major implementation-based language, though it knows that there should be 2 rows, it doesn't know the offset of the number of columns each row should have. So it doesn't have an answer for the question: "from which element should the second row start?".

Since the second row will be filled only after filling the first row in row-major implementation, and here since the number of columns is unknown, the compiler will never be able to get the answer for the above question, and thus it doesn't know which elements should do go the next row. It doesn't know the number of elements in each row due to the lack of offset on the number of columns each row should have.

And hence, regardless of the number of rows being mentioned or not, it is mandatory to mention the number of columns during array declaration in C.

vagdevi k
  • 1,478
  • 9
  • 25