Reputation: 8931
I have the following files structure that contain the definition of a struct an encapsulating type, when I try to access a member of the struct, I get the Member access into incomplete type
error. What is the problem?
foo_encoder.c:
#include "foo.h"
//...
struct FooEncoder {
int A;
int B;
foo_int32 C;
//...
}
foo.h:
extern "C" {
typedef struct FooEncoder FooEncoder;
//...
}
foo_interface.h:
typedef struct MyFooEncInst FooEncInst;
foo_interface.cc:
#include "foo_interface.h"
#include "foo.h"
//...
struct MyFooEncInst {
FooEncoder* encoder;
};
//...
MyFoo_Encode(FooEncInst* inst,...) {
//...
if (d > inst->encoder->C) { // This is where I get the error
//...
}
foo_int32
is defined in another place.
Upvotes: 5
Views: 37060
Reputation: 2500
The type you are trying to access is only forward declared at the time you try to access it. You can have a look at this question to learn what a forward declaration is while answers to this questions explain when you can use a forward declaration and when you cannot.
Your typedef in foo.h basically act as a forward declaration for type FooEncoder
. You include the file in foo_interface.cc. So the compiler knows, that the types exist but it does not know anything about its internals, like what members it has. Therefore it does not know if there is a member C
like you request it to access.
You need to tell the compiler how MyFooEncInst
and FooEncoder
look like internally for it to be able to access any members.
Upvotes: 1
Reputation: 43662
You're asking for a member in the FooEncoder
struct which isn't visible anywhere in your foo_interface.cc file. This looks similar to a pimpl idiom.
In order to have your code aware of FooEncoder
's structure you need to either
#include "foo_encoder.c"
in your foo_interface.cc file (I quite don't like this solution and you didn't post the full code either) or move your struct definition elsewhere in a header file and include that one (recommended).
Upvotes: 6
Reputation: 685
foo.h is declaring a type definition to a struct that is only defined in foo.c, so foo_interface.cc has no visibility as to what FooEncoder actually is. You can fix this by moving the struct definition from foo_encoder.c to foo.h.
Upvotes: 3