typedef 重新定义如何在 C11 中工作?
How is typedef redefinition meant to work in 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' 标志,重新定义也不会引发错误。
为什么不能重新定义带有结构的类型?
这是一个问题,其中定义来自第 3 方 headers。
在这些声明中
typedef struct {
int x;
} a_t;
typedef struct {
int x;
} a_t;
使用了两个未命名的结构,被认为是两种不同的类型。
所以别名 a_t
是为两种不同的类型定义的。
如果假设 typedef 使用相同的类型,那么在任何情况下都会重新定义未命名的结构,即它被定义了两次。
也就是说,如果你会写,例如
struct A
{
int x;
};
struct A
{
int x;
};
然后编译器也会发出类似的错误消息,在这种情况下结构 A 被重新定义。
尽管这两个结构具有相同的字段,但它们的类型不同。使用命名结构可以更清楚地看到这一点:
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
$
我读到在 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 方 headers。
在这些声明中
typedef struct {
int x;
} a_t;
typedef struct {
int x;
} a_t;
使用了两个未命名的结构,被认为是两种不同的类型。
所以别名 a_t
是为两种不同的类型定义的。
如果假设 typedef 使用相同的类型,那么在任何情况下都会重新定义未命名的结构,即它被定义了两次。
也就是说,如果你会写,例如
struct A
{
int x;
};
struct A
{
int x;
};
然后编译器也会发出类似的错误消息,在这种情况下结构 A 被重新定义。
尽管这两个结构具有相同的字段,但它们的类型不同。使用命名结构可以更清楚地看到这一点:
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
$