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

丹尼尔
#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.xand s.y,而不是s.something.xand s.something.y

没有标签的结构的每个声明都声明不同类型的原因是 C 2018 6.7.2.3 5 说:

… 不包含标签的结构、联合或枚举类型的每个声明都声明了一个不同的类型。

这样做的一个原因是有时我们出于不同目的使用具有相同内容的结构。例如,我们可能有一个包含两个double的结构用于复数(实部和虚部)和一个包含两个double的结构用于平面中的点(xy坐标):

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

让编译器将它们视为不同的类型意味着它可以向我们发出有关错误的警告,例如将 aPoint作为参数传递给aComplex预期。

正如您所指出的, atypedef为类型创建了一个新名称。然后使用typedef名称指代该现有类型。它不会“重复” 的声明struct并创建新类型。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么数据类型会冲突?

为什么在非指针结构上进行类型转换会导致语法错误

为什么以下使用IOmniThreadPool的代码会导致访问冲突?

为什么选择樱桃总是会导致合并冲突?

为什么vkCreateSwapchainKHR会导致访问冲突为0?

为什么更正“可选参数”会导致访问冲突?

为什么我的函数会产生“冲突类型”错误?

为什么iife中的包装函数会导致弱类型?

为什么这个sql会导致类型转换错误?

为什么解构数组项会导致联合类型?

为什么这个 TypeScript 类型会导致类似数组的结构,尽管它看起来像一个类似对象的类型?

为什么未初始化的指针会导致mem访问冲突接近于0?

Git:为什么变基会导致冲突而合并却不会?

为什么git pull origin development不进行-rebase会导致冲突?

为什么访问两个连续元素的线程会导致“银行冲突”?

为什么会导致错误?

使用别名引用匿名结构会导致错误

读取结构中包含的char会导致访问冲突异常

访问指向结构的指针会导致内存读取冲突

为什么这会导致访问冲突?

为什么编译器会自动为匿名类型生成Debugger属性?

为什么git revert会产生冲突?

为什么传递带有const引用成员的结构会导致C2280错误?

为什么将文件指针分配给结构指针成员会导致分段错误?

为什么完全启用 constexpr 数据结构会导致编译后的代码更大?

为什么带有匿名结构字段的结构不满足在该类型的别名上定义的方法?

为什么 JsonElement 是结构类型?

如果本地和远程文件之间存在差异,为什么拉取并不总是会导致冲突?

为什么在2个.CPP文件中包含此头文件(带有头保护)会导致命名冲突?