I was digging into a 3rd party code base and found that it is apparently valid to declare a type as a pointer to an undefined struct. As a minimum working example, consider a C file test.c
containing nothing but:
typedef struct foo *bar;
What surprises me is that this file compiles without any problems using the command
gcc test.c -shared
Why does the compiler not complain about the struct foo not being declared anywhere?
My environment is Ubuntu 16.04 with gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609.
The declaration above creates a forward declaration of struct foo
. Although you can't access its members, you can operate on a pointer to it.
This is commonly referred to as an opaque type, and is used to hide implementation details of a library from users of the library.
For example a library implementation may contain the following:
lib.c:
struct foo {
int f1;
};
struct foo *init()
{
return malloc(sizeof(struct foo));
}
void set1(struct foo *p, int val)
{
p->f1 = val;
}
int get1(struct foo *p)
{
return p->f1;
}
void cleanup(struct foo *p)
{
free(p);
}
The header file for this library might look like this:
lib.h:
struct foo;
struct foo *init(void);
void set1(struct foo *p, int val);
int get1(struct foo *p);
void cleanup(struct foo *p);
The user of this library would use the init
function to create an instance of the struct and the set1
and get1
functions to read / update the member. The user can't however create an instance of struct foo
or access the members without going through one of the interface functions.
Because pointer to structs have same size (for any structs). The size of a structure pointer doesn't depend on it's definition. Because no matter what, the pointer to it would be behaved the same way as any other structures pointer.