简体   繁体   English

为什么匿名结构会导致类型冲突

[英]Why do anonymous structs cause conflicting types

#define MyStruct(T) struct {T data;}

void foo(MyStruct(int) s);

void foo(MyStruct(int) s) {
    return;
}

int main(void) {
    //...
    return 0;
}

This results in an error:这会导致错误:

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);
     ^

There's no error if I create a typedef, such as typedef MyStruct(int) MyIntStruct;如果我创建一个 typedef 没有错误,比如typedef MyStruct(int) MyIntStruct; and use that.并使用它。

So my question is, why do I get the conflicting type error?所以我的问题是,为什么我会收到冲突的类型错误? Are all anonymous structs unique, like the compiler won't determine whether they're the exact same type?是否所有匿名结构都是唯一的,就像编译器不会确定它们是否完全相同?

First, these are structure declarations without tags, not anonymous structures.首先,这些是没有标签的结构声明,而不是匿名结构。 An anonymous structure is a structure without a name, not a structure declaration without a tag.匿名结构是没有名称的结构,而不是没有标签的结构声明。 For example:例如:

struct outer
{
    struct inner { int x; int y; };
    int z;
} s;

In this code, the struct member inside s does not have a member name, so it is anonymous.这段代码中, s里面s struct成员没有成员名,所以是匿名的。 We have no name that can refer to that structure, and we refer to its members as sx and sy , rather than s.something.x and s.something.y .我们没有可以引用该结构的名称,我们将其成员称为sxsy ,而不是s.something.xs.something.y

The reason each declaration of a structure without a tag declares a distinct type is C 2018 6.7.2.3 5 says:没有标签的结构的每个声明都声明不同类型的原因是 C 2018 6.7.2.3 5 说:

… Each declaration of a structure, union, or enumerated type which does not include a tag declares a distinct type. … 不包含标签的结构、联合或枚举类型的每个声明都声明了一个不同的类型。

A reason for this is sometimes we use structures that have identical contents for different purposes.这样做的一个原因是有时我们出于不同目的使用具有相同内容的结构。 For example, we might have a structure with two double values that we use for complex numbers (real and imaginary parts) and a structure with two double values that we use for points in a plane ( x and y coordinates):例如,我们可能有一个带有两个double值的结构用于复数(实部和虚部),还有一个带有两个double值的结构用于平面中的点( xy坐标):

typedef struct { double d[2]; } ComplexNumber;
typedef struct { double d[2]; } Point;

Having the compiler treat these as different types means it can give us warnings about mistakes like passing a Point as an argument where a Complex is expected.让编译器将它们视为不同的类型意味着它可以向我们发出警告,例如将Point作为参数传递给Complex的预期错误。

As you have noted, a typedef creates a new name for a type.正如您所指出的, typedef为类型创建了一个新名称。 Then using the typedef name refers to that existing type.然后使用typedef名称引用该现有类型。 It does not “repeat” the declaration of the struct and create a new type.它不会“重复” struct的声明并创建新类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM