#define MyStruct(T) struct {T data;}
void foo(MyStruct(int) s);
void foo(MyStruct(int) s) {
return;
}
int main(void) {
//...
return 0;
}
这会导致错误:
main.c:7:6: error: conflicting types for 'foo'
void foo(MyStruct(int) s) {
^
main.c:5:6: note: previous declaration is here
void foo(MyStruct(int) s);
^
如果我创建一个 typedef 没有错误,例如typedef MyStruct(int) MyIntStruct;
并使用它。
所以我的问题是,为什么我会收到冲突的类型错误?是否所有匿名结构都是唯一的,就像编译器不会确定它们是否完全相同?
首先,这些是没有标签的结构声明,而不是匿名结构。一个匿名的结构是没有名字的结构,而不是一个没有标签的结构声明。例如:
struct outer
{
struct inner { int x; int y; };
int z;
} s;
这段代码struct
里面的成员s
没有成员名,所以是匿名的。我们没有可以引用该结构的名称,我们将其成员称为s.x
and s.y
,而不是s.something.x
and s.something.y
。
没有标签的结构的每个声明都声明不同类型的原因是 C 2018 6.7.2.3 5 说:
… 不包含标签的结构、联合或枚举类型的每个声明都声明了一个不同的类型。
这样做的一个原因是有时我们出于不同目的使用具有相同内容的结构。例如,我们可能有一个包含两个double
值的结构用于复数(实部和虚部)和一个包含两个double
值的结构用于平面中的点(x和y坐标):
typedef struct { double d[2]; } ComplexNumber;
typedef struct { double d[2]; } Point;
让编译器将它们视为不同的类型意味着它可以向我们发出有关错误的警告,例如将 aPoint
作为参数传递给aComplex
预期。
正如您所指出的, atypedef
为类型创建了一个新名称。然后使用typedef
名称指代该现有类型。它不会“重复” 的声明struct
并创建新类型。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句