Search code examples
cstructdeclarationtypedefforward-declaration

Referencing an anonymous struct in itself


typedef struct {
    //
} list;

vs

typedef struct list{
    //
} list;

I have read in another posts (such as Using an anonymous struct vs a named struct with typedef) which says these two are almost equivalent and the only time when the later is required is when referencing the struct in itself.

However, the following compiles fine with clang and gcc:

#include <stdio.h>

typedef struct {
    struct list *next;
} list;

int main(){
 list l;
 return  0;
}

Above I have an anonymous struct referring to itself. How is this compiling?


Solution

  • For starters there is neither anonymous structure in your question. There are examples of unnamed structures.

    The notion of the anonymous structure is defined in the C Standard the following way (6.7.2.1 Structure and union specifiers)

    13 An unnamed member of structure type with no tag is called an anonymous structure; an unnamed member of union type with no tag is called an anonymous union. The members of an anonymous structure or union are considered to be members of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.

    As for this declaration

    typedef struct {
        struct list *next;
    } list;
    

    then there are declared two different types: unnamed structure with the alias name list and an incomplete declaration of the type struct list. list and struct list are two different incompatible types.

    For example if you will try this simple program

    #include <stdio.h>
    
    typedef struct {
        struct list *next;
    } list;
    
    int main(void) 
    {
        list lst1;
        list lst2;
        
        lst1.next = &lst2;
        
        return 0;
    }
    

    then the compiler will issue an error for this statement

    lst1.next = &lst2;
    

    saying that there is an assignment to ‘struct list *’ from incompatible pointer type ‘list *’.