Search code examples
cstructtypedefforward-declarationfunction-prototypes

Is it possible to consistently refer to forward-declared and non-forward-declared structs in C?


This doesn't work for foo

struct Foo;

typedef struct
{
    int x;
}
Bar;

void foo (Foo *); // unknown type name ‘Foo’

void bar (Bar *);

typedef struct
{
    int y;
}
Foo;

This doesn't work for bar

struct Foo;

typedef struct
{
    int x;
}
Bar;

void foo (struct Foo *);

void bar (struct Bar *); ‘struct Bar’ declared inside parameter list

typedef struct
{
    int y;
}
Foo;

Some of my structs have to be forward-declared, because they are passed as pointers, and some of them have to be not forward-declared, because they are passes as values.

Is there a way to declare types in C such that all function prototypes can consistently always refer to custom types in the same way, regardless of whether they are forward-declared or not?


Solution

  • Your problem is not forward-declared vs. non-forward-declared, it's struct X vs. typedef struct { ... } X.

    You can solve this by using struct X only:

    struct Foo;
    
    struct Bar
    {
        int x;
    };
    
    void foo (struct Foo *);
    void bar (struct Bar *);
    
    struct Foo
    {
        int y;
    };
    

    Once you have that, you can introduce typedef names:

    typedef struct Foo Foo;
    
    typedef struct
    {
        int x;
    }
    Bar;
    
    void foo (Foo *);
    void bar (Bar *);
    
    struct Foo
    {
        int y;
    };
    

    You can't pre-declare typedefs, so we still need a real struct type we can forward to. There's a small inconsistency here: Foo is the same as struct Foo, but there is no struct Bar, only Bar. You can fix that by switching to

    typedef struct Bar
    {
        int x;
    }
    Bar;
    

    This defines struct Bar and Bar simultaneously.