0

So, I have the following .h files: StudentRosterDef.h and StudentRoster.h

StudentRosterDef.h:

typedef struct Node *NodeP;
typedef struct Student *StudentP;

StudentRoster.h:

typedef struct StudentRoster *StudentRosterP;

//Below prototype creates empty studentroster and returns a NULL pointer
StudentRosterP newStudentRoster();

Now, I have the following .c file to accompany : StudentRoster.c

StudentRoster.c:

#include "StudentRosterDef.h"
#include "StudentRoster.h"

struct StudentRosterP
{
    NodeP root;
};

struct NodeP
{
    StudentP left;
    StudentP right;
};

StudentRosterP newStudentRoster()
{
    StudentRosterP thisRoster = (StudentRosterP) malloc(sizeof(StudentRosterP));
    thisRoster->root = 0x00;
    thisRoster = 0x00;
    return thisRoster;
};

Here is the message I get after running the gcc command on the terminal:

StudentRoster.c:27:12 : error: incomplete definition type of 'struct StudentRoster'
        thisRoster->root = 0x00;

        ~~~~~~~~^

./StudentRoster.h:14:16: note: forward declaration of 'struct StudentRoster'
    typedef struct StudentRoster *StudentRosterP;
                   ^

1 error generated.

The StudentRoster.h file can not be changed or modified in anyway as it is a supplied file and the .c and other accompanying .h files must be built to fit the description of StudentRoster.h exactly. Thanks for any help in advance!

like9orphanz
  • 55
  • 1
  • 9
  • Even if you have declared the type aliases, they still refer to the actual structures. If the code doesn't have the actual structures, then it can't use the type aliases. – Some programmer dude Nov 19 '14 at 19:11
  • See [Is it a good idea to `typedef` pointers?](http://stackoverflow.com/questions/750178/is-it-a-good-idea-to-typedef-pointers/) – Jonathan Leffler Nov 19 '14 at 19:19
  • Hm, I sort of get what you're saying, but could you extrapolate on that idea a little more please @JoachimPileborg – like9orphanz Nov 19 '14 at 19:21
  • Since there's a typo in the header name (`#include "StudentRsoter.h"`), we know you're not showing us the code that the compiler is seeing. (a) Be careful. (b) Show us the exact code, not an approximation, because you'll only get an approximation to the answer with the approximation to the real code. – Jonathan Leffler Nov 19 '14 at 19:22
  • @JonathanLeffler - The pointer being typedef is set in stone, I cannot change that. – like9orphanz Nov 19 '14 at 19:23
  • Bad luck; remember the alternative when you're in charge of the types. – Jonathan Leffler Nov 19 '14 at 19:24
  • @JonathanLeffler - That is the exact code, I must have just typo'd that one part, sorry, gonna edit it now – like9orphanz Nov 19 '14 at 19:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/65235/discussion-between-like9orphanz-and-jonathan-leffler). – like9orphanz Nov 19 '14 at 19:25
  • It can't be the exact code; there are 21 lines in the fragment and the compiler is complaining about line 27. You don't need the semicolon after the `}` at the end of the function definition. It marks a vacuous definition of an empty declaration. – Jonathan Leffler Nov 19 '14 at 19:26

2 Answers2

2

You need to define the types struct Node and struct StudentRoster instead of using the name the pointer typedefs (struct NodeP and struct StudentRosterP), so the following piece of code is probably what you actually mean:

struct StudentRoster  // No P
{
    NodeP root;
};

struct Node  // No P
{
    StudentP left;
    StudentP right;
};
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
brunocodutra
  • 2,329
  • 17
  • 23
0

You have:

typedef struct StudentRoster *StudentRosterP;

You also have:

struct StudentRosterP
{
    NodeP root;
};

These types are unrelated; you need:

struct StudentRoster // No P at the end here!
{
    NodeP root;
};

Rinse and repeat.

(Note that brunocodutra was saying much the same as this in his answer, but it perhaps wasn't stated quite so precisely or concisely, at least not at first.)


Could you explain why NOT having the Pointer as the struct definition would give me an error.

The P suffix is a human convention; the compiler doesn't know that the convention exists. When you define struct StudentRosterP, you still have not defined the struct StudentRoster that is required to access the internals of StudentRosterP thisRoster;. This defines a variable that is a pointer to an incomplete type struct StudentRoster. You can have and use such pointers as long as you don't need to access anything within the structure. They are 'opaque types' and very useful. But using thisRoster->root tries to access the internals of an opaque type, and that doesn't work.

I guess this is all just one more reason not to like using typedef with pointers, even though I understand your hands are tied about the type names.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Could you explain why NOT having the Pointer as the struct definition would give me an error. By the way, it worked, thank you very much! – like9orphanz Nov 19 '14 at 19:36