C 每个结构有不同类型的原因可以解释吗?

C 每个结构有不同类型的原因可以解释吗?,c,struct,memory-layout,C,Struct,Memory Layout,例如,由于可能的对齐,指向不同类型的指针不能直接相互转换(可能不是完全正确的语句,但您无论如何都不了解我的想法)。是否有类似的技术原因导致您无法执行类似操作: struct A { int a, b; } ; struct B { int a, b; } ; void func(struct A a, struct B b) { a = b; } 现在删除我并编辑这个问题,如果你理解它(在一些奇怪的情况下),并将其翻译给公众 在c语言中,什么时候具有相同上下文的两个

例如,由于可能的对齐,指向不同类型的指针不能直接相互转换(可能不是完全正确的语句,但您无论如何都不了解我的想法)。是否有类似的技术原因导致您无法执行类似操作:

struct A
{
    int a, b;
} ;

struct B
{
    int a, b;
} ;

void func(struct A a, struct B b)
{
    a = b;
}
现在删除我并编辑这个问题,如果你理解它(在一些奇怪的情况下),并将其翻译给公众

在c语言中,什么时候具有相同上下文的两个不同结构可以真正创建不同的类型

他们总是这样<代码>结构A和结构B是不同的类型

struct A {
    int a, b;
} ;

struct B {
    int a, b;
} ;
这被禁止的原因纯粹是因为它对于编译器来说太复杂了,还是其他原因

它对于编译器来说并不太复杂。最好将它们分开。如果需要相同,代码可以使用
typedef

typedef struct A foo;
typedef struct A bar;

int main(void) {
  foo1 x;
  bar1 y = x;
  struct B z = x; // does not compile
}
为什么不允许结构bz=x?这就是语言设计。如果防止像下面这样的愚蠢代码。尽管
struct JustLikeFILE
文件
具有相同的字段,但从概念上讲,它不是
文件

void f(void) {
  FILE *f = fopen("abc","r");
  struct JustLikeFILE g = *f;  // does not compile
}

C标准定义了“类型兼容性”,对于要兼容的结构类型,除其他标准外,它们必须使用相同的标记。您的结构使用不同的标记-它们本质上是不同的类型

struct A {
    int a, b;
} ;

struct B {
    int a, b;
} ;
您可以在标准中一些措辞复杂的规范中找到肮脏的细节:

ISO/IEC 9899:2011§6.2.7兼容型和复合型 如果两种类型的类型相同,则它们具有兼容的类型。确定两种类型是否兼容的其他规则在6.7.2中针对类型说明符进行了描述,在6.7.3中针对类型限定符进行了描述,在6.7.6中针对声明符进行了描述,如果单独翻译单元中声明的或枚举类型的标记和成员满足以下要求,则它们是兼容的:如果一个使用标记声明,另一个应使用相同的标记声明。如果两者都是在各自翻译单元内的任何地方完成的,则以下附加要求适用:其成员之间应存在一对一的对应关系,以便每对对应成员声明兼容类型;如果使用对齐说明符声明对中的一个成员,则使用等效对齐说明符声明另一个成员;如果该对中的一个成员用名称声明,则另一个成员用相同的名称声明。对于两个结构,应按照相同的顺序声明相应的构件。对于两个结构或接头,相应的位字段应具有相同的宽度。对于两个枚举,相应的成员应具有相同的值

55)两种类型不必完全相同即可兼容

由于您的两个示例结构具有不同的标记(
struct A
struct B
),它们显然不是兼容的类型

第二个示例使用两种匿名
struct
类型:

struct { int a, b; } func1();

void func2()
{
    struct { int a, b; } var = func1(); //not allowed
}
本标准的另一部分适用于:

6.7.2.1结构和联合规范 ^8结构或联合说明符中的结构声明列表在翻译单元内声明新类型。结构声明列表是结构或联合成员的一系列声明

引用的结构声明列表是大括号
{
..
}
中的部分。因为在一个翻译单元中有两个,所以它们声明(定义)两种类型,因此不兼容

最后一个例子是
typedefint myOrangeInt
typedef int myAppleInt
说明C中的
typedef
没有引入新类型;它只是引入了另一种类型的同义词。在本例中,
myOrangeInt
int
的同义词,
myAppleInt
也是如此,因为它们是相同类型的同义词,所以类型是相同的类型

§6.7.8类型定义 ^3.
typedef
声明不引入新类型,只引入指定类型的同义词


考虑类型-苹果和橙子。它们是一样的吗?两者都可以根据果汁含量和体积来定义。i、 e.两个价值观。但您会比较它们吗?我们决定根据结构名称(标记)而不是结构进行比较。从长远来看,这对您有利。@JonathanLeffler确切地说是什么?
static\u assert(sizeof a==sizeof b);memcpy(a&b、a尺寸)您的标题与问题也不匹配。标题的答案是“每次”:
struct A
struct B
是不同的类型。(标准也是这么说的)。但是,您的文本提出了一系列模糊的问题,这些问题可以概括为“为什么具有相同成员的两个结构不是相同的类型?”如果我键入def
JustLikeFILE
?为什么它与typedefs一起工作而不与structures一起工作。FISOCPP
typedef struct JustLikeFILE F_type
创建一个别名
F_type
,该别名与
struct JustLikeFILE
相同。不是新的类型。