c-typedef重新定义如何在C11中工作



我读到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被重新定义。

最新更新