typedef 重定义在 C11 中如何工作?

lip*_*ipi 4 c struct typedef definition redefinition

我读到在 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;
}
Run Code Online (Sandbox Code Playgroud)

当使用 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.

Run Code Online (Sandbox Code Playgroud)

有趣的是,如果 typedef 只是一个原始类型(即“typedef int a_t;”),那么即使没有“-std=c11”标志,重新定义也不会抛出错误。

为什么不能重新定义具有结构的类型?

这是一个来自第三方标头的定义的问题。

kay*_*lum 5

尽管两个结构体具有相同的字段,但它们的类型不同。通过命名结构可以更清楚地看到这一点:

struct first {
    int x;
};

struct second {
    int x;
};
Run Code Online (Sandbox Code Playgroud)

显然,这是两个不同的结构,即使它们具有相同的字段。

因此,在您的情况下,可以定义单个命名结构,然后 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
$ 
Run Code Online (Sandbox Code Playgroud)