Why do I keep getting "error: variable has incomplete type 'struct intVec'?

30,208

There is no structure definition struct IntVec.

So the compiler is unable to define the object v

struct IntVec v;

I think you mean

IntVec v;

And this call

v.intVecPush(v,0);

is invalid and does not make sense. I think there should be something like

IntVec v = intMakeEmptyVec();
intVecPush(v,0);

instead of

struct IntVec v;
v.intVecPush(v,0);

Also it is a bad idea to include the whole module in another module. You should place the structure definition in the header and include this header in the compilation unit with main.

That is move these definitions

typedef struct IntVecNode {
    int* data;
    int sz;         // Number of elements that contain data
    int capacity;   // How much is allocated to the array
} IntVecNode;
typedef struct IntVecNode* IntVec;

in the header.

Share:
30,208
Author by

Jamie Nguyen

Updated on July 09, 2022

Comments

  • Jamie Nguyen 6 months

    I'm doing an assignment for my data structures class and I have very little experience with C structures and C in general. This is the .h file that I was given to do the assignment:

    #ifndef C101IntVec
    #define C101IntVec
    typedef struct IntVecNode* IntVec;
    static const int intInitCap = 4;
    int intTop(IntVec myVec);
    int intData(IntVec myVec, int i);
    int intSize(IntVec myVec);
    int intCapacity(IntVec myVec);
    IntVec intMakeEmptyVec(void);
    void intVecPush(IntVec myVec, int newE);
    void intVecPop(IntVec myVec);
    #endif
    

    This is the .c implementation that I've made:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "intVec.h"
    typedef struct IntVecNode {
        int* data;
        int sz;         // Number of elements that contain data
        int capacity;   // How much is allocated to the array
    } IntVecNode;
    typedef struct IntVecNode* IntVec;
    //static const int intInitCap = 4;
    int intTop(IntVec myVec) {
        return *myVec->data;
    }
    int intData(IntVec myVec, int i) {
        return *(myVec->data + i);
    }
    int intSize(IntVec myVec) {
        return myVec->sz;
    }
    int intCapacity(IntVec myVec) {
        return myVec->capacity;
    }
    IntVec intMakeEmptyVec(void) {
        IntVec newVec = malloc(sizeof(struct IntVecNode));
        newVec->data = malloc(intInitCap * sizeof(int));
        newVec->sz = 0;
        newVec->capacity = intInitCap;
        return newVec;
    }
    void intVecPush(IntVec myVec, int newE) {
        if (myVec->sz >= myVec->capacity) {
            int newCap = myVec->capacity * 2;
            myVec->data = realloc(myVec->data, newCap * sizeof(int));
        } else {
            for (int i = 0; i < myVec->capacity; i++) {
                *(myVec->data + i) = *(myVec->data + i + 1);
            }
            myVec->data = &newE;
        }
        myVec->sz++;
    }
    void intVecPop(IntVec myVec) {
        for (int i = 0; i < myVec->capacity; i++) {
            *(myVec->data - i) = *(myVec->data - i + 1);
        }
        myVec->sz--;
    }
    

    This is the test file:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "intVec.c"
    int main() {
        struct IntVec v;
        v.intVecPush(v,0);
        return 0;
    }
    

    Every time I run the test file, I get the error:

    test.c:7:16: error: variable has incomplete type 'struct IntVec'
            struct IntVec v;
                          ^
    test.c:7:9: note: forward declaration of 'struct IntVec'
            struct IntVec v;
                   ^
    1 error generated.
    

    I've tried changing the #include "intVec.c" to "intVec.h" in the test file, however that produces the same error. What would I need to change in order to not get this error?

    • melpomene
      melpomene over 5 years
      Use a type that actually exists. There is no struct IntVec in your code.
    • user2357112
      user2357112 over 5 years
      Also, you should be including the .h file instead of the .c file. It is extremely rare for including a .c file to be the right thing to do.
    • M.M
      M.M over 5 years
      Change main to IntVec v = intMakeEmptyVec(); intVecPush(v, 0);. Although I would recommend not using pointer typedefs as they are confusing (it looks like your code is copying an intvec by value when in fact it is not)
    • ikegami
      ikegami over 5 years
      Code using this library will leak! (There's no way to free the vec)
  • Vlad from Moscow
    Vlad from Moscow over 5 years
    @JamieNguyen As I have pointed in my answer you have to write at least IntVec v; instead of struct IntVec v;
  • Jamie Nguyen over 5 years
    Changing struct IntVec; to IntVec; i get: test.c:8:3: error: member reference type 'IntVec' (aka 'struct IntVecNode ') is a pointer; did you mean to use '->'? v.intVecPush(v,0); ~^ -> test.c:8:3: error: incomplete definition of type 'struct IntVecNode' v.intVecPush(v,0); ~^ ./intVec.h:11:16: note: forward declaration of 'struct IntVecNode' typedef struct IntVecNode IntVec; ^ 2 errors generated. Changing the v.IntVecPush(v,0) to v->IntVecPush(v,0) brings me back to the incomplete type error again.
  • Vlad from Moscow
    Vlad from Moscow over 5 years
    @JamieNguyen See my updated post. It seems you do not understood what you are doing.