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 中工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何为拥抱脸重新下载标记器?

消费者再平衡如何在 Kafka 中工作?

udf(用户定义函数)如何在 pyspark 中工作?

plexus 注释是不是在 Maven 插件中工作?

JavascriptExecutor 如何在 selenium webdriver 中工作

如何定义在 Laravel 数据库迁移中工作的非 id 主键?