How is typedef redefinition meant to work in C11?

Viewed 453

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.

2 Answers

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
$ 

In these declarations

typedef struct {
    int x;
} a_t;

typedef struct {
    int x;
} a_t;

there are used two unnamed structures that are considered as two different types.

So the alias name a_t is defined for two different types.

If to imagine that the typedefs use the same type then in any case the unnamed structure is redefined that is it is defined twice.

That is if you will write for example

struct A
{
    int x;
};

struct A
{
    int x;
};

then the compiler also will issue a similar error message that in this case the structure A is redefined.

Related