SIMEL
SIMEL

Reputation: 8931

Member access into incomplete type error

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

Answers (3)

sigy
sigy

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

Marco A.
Marco A.

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

diametralpitch
diametralpitch

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

Related Questions