Search code examples
cstructdeclarationtypedef

Why can you use a typedef'd struct before the typedef?


Here's a MWE:

#include <stdlib.h>

typedef struct node_type {
    struct node* next;
    struct node* prev;
} node;

int main(int argc, char* argv[]) {
    node* n = (node*)malloc(sizeof(node));
}

Not having struct before node* in the struct definition will error; node has not yet been defined. However, struct node* works fine, even though only struct node_type has been defined at this point. Why does this work?

Intuitively, it compiles if the struct is defined with struct node_type* for its fields, or if there is an explicit typedef before and the fields are of type node*. However, I don't understand why an in-line typedef allows the fields to be of type struct node* but not of type node*.


Solution

  • Not having struct before node* in the struct definition will error; node has not yet been defined. However, struct node* works fine, even though only struct node_type has been defined at this point.

    In this typedef declaration

    typedef struct node_type {
        struct node* next;
        struct node* prev;
    } node;
    

    there are declared two structure types. The first one, struct node_type, is a complete type, and the second one, struct node, is an incomplete type.

    Apart from these declarations, the code introduces an alias node for the type specifier struct node_type.

    You may write

    node* n = (node*)malloc(sizeof(node));
    

    but you may not write for example

    n->next = ( node * )malloc( sizeof( node ) );
    

    or

    n->next = malloc( sizeof( struct node ) );
    

    because the type struct node is an incomplete type. Its size is unknown. And struct node * and node * are incompatible pointer types.

    As for your question then if you will write for example

    typedef struct node_type {
        node* next;
        node* prev;
    } node;
    

    then in these member declarations

    node* next;
    node* prev;
    

    the name node is not defined yet. So, the compiler issues an error message.