What is 'forward declaration' and the difference between 'typedef struct X' and 'struct X'?

r_goyal picture r_goyal · Sep 6, 2013 · Viewed 61.8k times · Source

I am a beginner in C programming and I know the difference between struct type declaration and typedef struct declaration. I came across to know an answer saying that if we define a struct like:

typedef struct { 
    some members;
} struct_name;

Then it will be like providing an alias to an anonymous struct (as it is not having a tag name). So it can't be used for forward declaration. I don't know what the forward declaration means.

Also, I wanted to know that for the following code:

typedef struct NAME { 
    some members;
} struct_alias;

Is there any difference between NAME and struct_alias? Or are both equal as struct_alias is an alias of struct NAME ?

Furthermore, can we declare a variable of type struct NAME like these:

struct_alias variable1;

and/or like:

struct NAME variable2;

or like:

NAME variable3; 

Answer

Sergey L. picture Sergey L. · Sep 6, 2013

struct forward declarations can be useful when you need to have looping struct declarations. Example:

struct a {
    struct b * b_pointer;
    int c;
};

struct b {
    struct a * a_pointer;
    void * d;
};

When struct a is declared it doesn't know the specs of struct b yet, but you can forward reference it.

When you typedef an anonymous struct then the compiler won't allow you to use it's name before the typedef.

This is illegal:

struct a {
    b * b_pointer;
    int c;
};

typedef struct {
    struct a * a_pointer;
    void * d;
} b;

// struct b was never declared or defined

This though is legal:

struct a {
    struct b * b_pointer;
    int c;
};

typedef struct b {
    struct a * a_pointer;
    void * d;
} b;

// struct b is defined and has an alias type called b

So is this:

typedef struct b b;
// the type b referes to a yet undefined type struct b

struct a {
    b * struct_b_pointer;
    int c;
};

struct b {
    struct a * a_pointer;
    void * d;
};

And this (only in C, illegal in C++):

typedef int b;

struct a {
    struct b * struct_b_pointer;
    b b_integer_type;
    int c;
};

struct b {
    struct a * a_pointer;
    void * d;
};

// struct b and b are two different types all together. Note: this is not allowed in C++