0

I want to move the array in another function (type void), to change the value of the array, but every times i have got an error under gcc

I have those following rules:

  1. in this exercise it's forbidden to use global variable,
  2. We want to move the array by reference and not use pointers:

.

#include <stdio.h>

typedef enum {F=0,T=1} Mat;

//==========================//

void unknown(Mat b[][][]){
    b[0][0][0]=7;
    printf("%d\n",b[0][0][0]);
}

//=========================//

int main(void){

    Mat b[2][2][2];

    b[0][0][0]=1;
    printf("%d\n",b[0][0][0]); //before the unknown

    uknown(b);
    printf("%d\n",b[0][0][0]); //after unknown
    return 0;
}

I have the following error:

test.c:7:18: error: array type has incomplete element type ‘Mat[] {aka enum []}’ void unknown(Mat b[][][]){ ^ test.c: In function ‘main’: test.c:21:9: error: type of formal parameter 1 is incomplete unknown(b); ^

The question is : I need to change the value of the array, not in main, but in the function void unknown, and check in the main (after having change in void unknown values of array Mat b) if this array change this value by reference, what's wrong ? and what do I need to change inside the code ?

(my gcc version: gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609)

Elias Van Ootegem
  • 67,812
  • 9
  • 101
  • 138
animals
  • 1
  • 1
  • 2
    In the unknown function, you must specify the last two dimensions, and may specify the first. `Mat b[][2][2]`. – Jonathan Leffler Dec 29 '16 at 16:52
  • 2
    About your rule #2, in C there is no concept of a reference. And in this case you are effectively passing by pointer. You can lookup "array decay" for more info. This answer elaborates more http://stackoverflow.com/questions/1461432/what-is-array-decaying#1461449 – diametralpitch Dec 29 '16 at 17:11
  • Just so you know `b[2][2][2]` and `b[8]` are interchangeable here, and arrays decay into pointers when you pass them to functions, so `Mat b[8];` and `void unknown(Mat *b)` might make your code easier to read – Elias Van Ootegem Dec 29 '16 at 17:11
  • 1
    Possible duplicate of [GCC: array type has incomplete element type](http://stackoverflow.com/questions/10003270/gcc-array-type-has-incomplete-element-type) – emlai Dec 29 '16 at 22:59
  • @EliasVanOotegem: I don't see how `b[2][2][2]` and `b[8]` can be equivalent. The first takes three subscripts to find the underlying value; the second only requires one subscript. At the very least, you've grotesquely over-simplified what you're trying to say. At worst, you're flat out wrong. – Jonathan Leffler Dec 30 '16 at 04:40
  • @JonathanLeffler: I know it's a gross oversimplification (and perhaps confusing representation) of how arrays work. I was referring to things like matrices in unions [like here](https://eval.in/706494). Depending on how/what you need, you may prefer the flat array over the matrix. Both `int[2][2][2]` and `int[8]` are equal in size. Coupled with the array decay, it may be something the OP could exploit here – Elias Van Ootegem Dec 30 '16 at 11:36

1 Answers1

1

You must specify all array dimensions except the first when you pass the array to a function; you may specify the first dimension.

Thus:

#include <stdio.h>

typedef enum { F = 0, T = 1 } Mat;

static void unknown(Mat b[][2][2])
{
    b[0][0][0] = 7;
    printf("%d\n", b[0][0][0]);
}

int main(void)
{
    Mat b[2][2][2];

    b[0][0][0] = 1;
    printf("%d\n", b[0][0][0]);

    unknown(b);
    printf("%d\n", b[0][0][0]);
    return 0;
}

Output:

1
7
7

You could also write: void unknown(Mat b[2][2][2]).

The static is needed to quell a compiler warning under my default compilation options. Since there isn't any other source file, the function doesn't need to be visible outside this file and can be static. Alternatively, I could declare the function: extern void unknown(Mat b[][2][2]); before defining it — that would also satisfy the options I use. (The extern is optional, but I use it, even though there are others who excoriate the practice; it is symmetric with how global variables need to be declared on those rare occasions when I use one.) I don't make any variable or function visible outside its source file unless there's a compelling reason for it to be visible — not even when it's a single file compilation. If the function should be visible outside the source file, it should be declared in a header that is used both in the source file where the function is defined and in all the source files that use the function. That ensures that the definition and declarations are consistent.

Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185