cstructtypedefdefinitionredefinition

How is typedef redefinition meant to work in C11?


I read that in C11 typedef redefinition is allowed, as long as the definitions are the same. However the following code

typedef struct {
    int x;
} a_t;

typedef struct {
    int x;
} a_t;

int main(int argc, char* argv[]) {
    a_t a;
    return a.x + argc;
}

when compiled with C11 flag gives me a redefinition error:

% clang -std=c11 -o x x.c
x.c:7:3: error: typedef redefinition with different types ('struct a_t' vs 'struct a_t')
} a_t;
  ^
x.c:3:3: note: previous definition is here
} a_t;
  ^
1 error generated.

Interestingly, if the typedef is just a primitive type (i.e. 'typedef int a_t;') then redefinition does not throw error, even without the '-std=c11' flag.

Why can't types with structs be redefined?

This is an issue where definitions coming from 3rd party headers.


Solution

  • The two structs are not the same type even though they have the same fields. One can see this more clearly with named structs:

    struct first {
        int x;
    };
    
    struct second {
        int x;
    };
    

    Clearly these are two different structs even though they have the same fields.

    So in your case a single named struct can be defined and then typedef redefinitions will work.

    $ cat test.c
    struct A {
        int x;
    };
    
    typedef struct A a_t;
    typedef struct A a_t;
    
    int main(void)
    {
    
    }
    
    $ clang -std=c99 test.c
    test.c:6:18: warning: redefinition of typedef 'a_t' is a C11 feature
          [-Wtypedef-redefinition]
    typedef struct A a_t;
                     ^
    test.c:5:18: note: previous definition is here
    typedef struct A a_t;
                     ^
    1 warning generated.
    
    $ clang -std=c11 test.c
    $