0

In the example below I don't understand why I get this error:

test.c:3:6: error: array type has incomplete element type

Here, the compiler should consider a complete type i.e. [2][3] because each sub-element has a size of 3. So, where is the problem?

long foo[2][] = {
    {2,3,4},
    {5,6,7}
}; 

If I complete the type using foo[2][3] I will get this error:

test.c:9:5: note: expected ‘long int *’ but argument is of type ‘long int (*)[3]’
 int bar(long* list, size_t size)

Using this example:

int bar(long* list, size_t size);

int main() {    
    bar(&foo[0], sizeof(foo[0]));
    return 0;
}       

How can I fix it?

nowox
  • 25,978
  • 39
  • 143
  • 293

3 Answers3

3

You can only leave out the dimension on the leftmost side, i.e. you can do

long foo[][3] = { { 2, 3, 4 }, { 5, 6 ,7 } };

but not the other way around like you tried. It's simply not supported, perhaps because checking that the lengths of all sub-arrays are the same was deemed to costly, or whatever.

For the second problem the fact that you get an * in the error should lead you to remove the & in the call. You want the sub-array, which will decay to a pointer to the first element, not a pointer to an array.

Also, remember that sizeof returns the size in number of chars, so for an array you need to scale down:

bar(foo[0], sizeof foo[0] / sizeof foo[0][0]);
unwind
  • 391,730
  • 64
  • 469
  • 606
  • With your example I still get the error `note: expected ‘long int *’ but argument is of type ‘long int (*)[3]’` – nowox May 13 '16 at 10:56
2

Here, the compiler should consider a complete type i.e. [2][3] because each sub-element has a size of 3. So, where is the problem?

If you had it like:

long foo[2][] = {
    {2,3,4},
    {5,7}
};

What should the compiler do in this case? Is it [2][2] or [2][3]?

In C, it's only possible to omit the left most dimension of an array. So, you can do:

long foo[][3] = {
    {2,3,4},
    {5,6,7}
};

Relevant post: why c/c++ allows omission of leftmost index of a multidimensional array in a function call?

note: expected ‘long int ’ but argument is of type ‘long int ()[3]’ int bar(long* list, size_t size)

This is because the type you pass and bar expect don't match. My personal choice is to use:

int bar(long (*list)[3], size_t size) {

}

and call:

bar(foo, sizeof foo/sizeof foo[0]);

But there are other ways too. See: How to pass 2D array (matrix) in a function in C?

Community
  • 1
  • 1
P.P
  • 117,907
  • 20
  • 175
  • 238
0

Yes below code will not compile as:

long foo[2][] = {
    {2,3,4},
    {5,6,7}
}; 

declaration of 'foo' as multidimensional array must have bounds for all dimensions except the first long foo[2][] = {

you can successfully compile the below code:

long foo[][3] = {
    {2,3,4},
    {5,6,7}
}; 

I am able to successfully compile the below code:

long foo[2][3] = {
        {2,3,4},
        {5,6,7}
    }; 


  ^
Nargis
  • 4,687
  • 1
  • 28
  • 45
  • You didn't cover the second error: `test.c:9:5: note: expected ‘long int *’ but argument is of type ‘long int (*)[3]’` – machine_1 May 13 '16 at 10:09