我读到C11中允许typedef重新定义,只要定义相同。但是以下代码
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;
}
当使用C11标志编译时,会给我一个重新定义错误:
% 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.
有趣的是,如果typedef只是一个基元类型(即"typedef int a_t;"(,那么即使没有"-std=c11"标志,重定义也不会引发错误。
为什么不能重新定义具有结构的类型?
这是一个定义来自第三方标头的问题。
这两个结构不是同一类型,即使它们有相同的字段。通过命名结构可以更清楚地看到这一点:
struct first {
int x;
};
struct second {
int x;
};
很明显,这是两种不同的结构,尽管它们有相同的字段。
因此,在您的情况下,可以定义一个命名结构,然后typedef重新定义就可以工作了。
$ 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
$
在这些声明中,
typedef struct {
int x;
} a_t;
typedef struct {
int x;
} a_t;
使用了被认为是两种不同类型的两个未命名结构。
因此,别名a_t
是为两种不同的类型定义的。
如果假设typedef使用相同的类型,那么在任何情况下,未命名的结构都会被重新定义,也就是说,它被定义了两次。
那是如果你要写例如
struct A
{
int x;
};
struct A
{
int x;
};
那么编译器也将发出类似的错误消息,在这种情况下结构a被重新定义。