0

I looked at this SO post with no help.

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

Error

$ gcc  a.c                                                                      
a.c:6:8: error: array has incomplete element type 'int []'
  int a[][] = {{1,2},{3,4}};
       ^
1 error generated.

Why is a[][] incomplete type?

Why is int a[][2] fine?

I would've assumed that since compiler can initialize this 2-D array it can also figure out bounds automatically? I know that I'm required to provide size but why? Is it language requirement?

JamesWebbTelescopeAlien
  • 3,547
  • 2
  • 30
  • 51

2 Answers2

2

Only one index can autosize. Otherwise you could have any pair of factors in the size. So a[][2] works, but a[][] does not, because it can't guess the size of the array of arrays.

JamesWebbTelescopeAlien
  • 3,547
  • 2
  • 30
  • 51
MarcD
  • 588
  • 3
  • 11
  • 1
    well, it could work out the size of the arrays from the initializer in this case. Just the language spec happens to say that it shouldn't do that. – M.M Oct 12 '16 at 03:17
  • In this case, yes, but in most cases no. Try six elements. Is it [2][3], or [3][2]? – MarcD Oct 12 '16 at 03:18
  • 3
    If they're braced as in the OP, there's no ambiguity – M.M Oct 12 '16 at 03:18
  • @MarcD I know that I'm required to add size but my question is what is the reason? Is it language requirement? If yes then why? – JamesWebbTelescopeAlien Oct 12 '16 at 03:23
  • The compiler adds an element to the left of the array in memory that specifies the number of elements. This is for destruction purposes, especially for user defined types that have a destructor. It has to know how many times to call the destructor when the array is destroyed. While you don't have to specify the size of an array, the size of the elements does need to be known, hence the reason for the [][2]. It's really an array of arrays of size 2. – MarcD Oct 12 '16 at 03:40
  • @NulledPointer I think that the reason is they wanted to keep compiler simple in the old times. It could have been added in the later standards, but no-one has really needed or cared about the feature enough to implement it. – user694733 Oct 12 '16 at 07:04
1

Here's the problem:

6.2.5 Types
...
An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type. The element type shall be complete whenever the array type is specified. Array types are characterized by their element type and by the number of elements in the array. An array type is said to be derived from its element type, and if its element type is T, the array type is sometimes called ‘‘array of T’’. The construction of an array type from an element type is called ‘‘array type derivation’’.

A 2D array is actually a 1D array where each element has array type. You can think of the declaration

T a[][N];

as having been written

typedef T R[N];
R a[];

Per the rule above, R must be a complete type; that means that if R is an array type, its size must be known. You could not write

typedef T R[];
R a[];

meaning you cannot write

T a[][];

This is irrespective of the presence of any initializer.

John Bode
  • 119,563
  • 19
  • 122
  • 198