typedef 重新定义如何在 C11 中工作?
Posted
技术标签:
【中文标题】typedef 重新定义如何在 C11 中工作?【英文标题】:How is typedef redefinition meant to work in C11? 【发布时间】:2021-08-27 22:19:22 【问题描述】:我读到在 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' 标志,重新定义也不会引发错误。
为什么不能重新定义带有结构的类型?
这是来自第 3 方标头的定义的问题。
【问题讨论】:
这两个structs
不是同一类型,即使它们具有相同的字段。您可以做的是定义一个(单个)命名结构,然后为该命名结构定义多个相同的 typedef。
@kaylum:这应该是一个答案。
我怀疑有些人已经在写答案了,但如果您正在寻找标准参考,它是 6.7.2.3 (5):“结构、联合或枚举类型的每个声明不包含标签声明了不同的类型。”即使它们具有相同顺序的相同成员也是如此;这种情况也不例外。
【参考方案1】:
这两个结构虽然具有相同的字段,但它们的类型不同。使用命名结构可以更清楚地看到这一点:
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
$
【讨论】:
感谢@kaylum,这确实有道理。不幸的是,第 3 方标头都在其 typedef 中使用匿名结构,所以我将不得不找到其他一些解决方案。【参考方案2】:在这些声明中
typedef struct
int x;
a_t;
typedef struct
int x;
a_t;
使用了两种未命名的结构,它们被视为两种不同的类型。
所以别名a_t
是为两种不同的类型定义的。
如果想象 typedef 使用相同的类型,那么无论如何都会重新定义未命名的结构,即它被定义了两次。
那就是如果你会写例子
struct A
int x;
;
struct A
int x;
;
然后编译器也会发出类似的错误消息,在这种情况下结构 A 被重新定义。
【讨论】:
以上是关于typedef 重新定义如何在 C11 中工作?的主要内容,如果未能解决你的问题,请参考以下文章