In the header, declare the structure type as an incomplete type. For example:
typedef struct struct1 struct1;
extern void func1(struct1 *p1);
Or:
struct struct1;
void func1(struct struct1 *p1);
You can mix'n'match extern
or not and typedef
vs struct tag
.
In the implementation code (or implementation header if you have multiple source files implementing the support for the type), you include the public header and define the structure type:
struct struct1
{
…private details…
};
In C11 and beyond, you can repeat a typedef
as long as it refers to the same type; in earlier versions of C, you could not do that.
The advantage of this approach is that the client code is forced to use your functions because they don't know the internals of the structure, but they get a measure of type safety. In particular, a random structure pointer can't be passed to this function. If everything takes void *
, then you can pass a wrong structure type to the function because all void
pointers look alike. That's both unkind and unnecessary.