兼容类型(三)
四、结构、联合、枚举的兼容性
① 结构的兼容性
在同一编译单元内,每个结构都是一个新类型,与其它结构类型既不相同,也不兼容。
struct {int age; char *name;} a; struct {int age; char *name;} b; struct student {int age; char *name;} c;
结构变量a、b、c的类型是不相同的,也是不兼容的。尽管a、b的类型看上去一样,但它们依然是不同的类型。
如果两个结构变量的类型相同,则这两个结构变量的类型是兼容的。如果结构变量的类型是先前定义的结构类型,则其类型与先前定义的结构类型是相同类型。相同类型一定是兼容类型。
struct {int age; char *name;} a, b; struct student {int age; char *name;} c; struct student d;
结构变量a、b的类型是相同的,也是兼容的;结构变量c、d的类型是相同的,也是兼容的。
在不同的编译单元中声明的两个结构类型如果是兼容的,应满足下述条件:
- 如果一个结构类型有标记(tag),另一个结构类型应具有相同的标记;
- 如果两个结构类型都是完整类型,结构成员应该一一对应,具体包括:结构成员的类型应该是兼容的;结构成员数、结构成员名及其顺序应该是相同的;如果存在对齐说明符,应具有等价的对齐说明符;如果存在位字段,位字段的宽度应该是相同的。
/* A编译单元。*/ struct student;
/* B编译单元。*/ struct student {int age; char *name;};
/* C编译单元。*/ struct student {int age; char *surname;};
/* D编译单元。*/ struct teacher {int age; char *name;};
由于标记不同,A编译单元、B编译单元、C编译单元的结构类型与D编译单元内的结构类型是不兼容的。A编译单元内的结构类型与B编译单元、C编译单元内的结构类型是兼容的;A编译单元内的结构类型是不完整类型,B编译单元、C编译单元内的结构类型都是完整类型,在标记相同的情况下,不完整类型与完整类型是兼容的。B编译单元内的结构类型与C编译单元内的结构类型是不兼容的,它们都是完整类型,要求结构成员一一对应,结构成员名要求相同。
② 联合的兼容性
在同一编译单元内,每个联合都是一个新类型,与其它联合既不相同,也不兼容。
union {int x; double y;} a; union {int x; double y;} b; union number {int x; double y;} c;
联合变量a、b、c的类型是不相同的,也是不兼容的。尽管a、b的类型看上去一模一样,但它们依然是不同的类型。
如果类型说明符是先前定义的联合类型,则该类型与先前定义的联合类型是相同的类型。相同联合类型都是兼容的。
union {int x; double y;} a, b; union number {int x; double y;} c; union number d;
联合变量a、b的类型是相同的,也是兼容的;联合变量c、d的类型是相同的,也是兼容的。
在不同的编译单元中声明的两个联合类型如果是兼容的,应满足下述条件:
- 如果一个联合类型有标记(tag),另一个联合类型应具有相同的标记。
- 如果两个联合类型都是完整类型,联合成员应该一一对应,具体包括:联合成员的类型应该是兼容的;联合成员数、联合成员名应该是相同的;如果存在对齐说明符,应具有等价的对齐说明符;如果存在位字段,位字段的宽度应该是相同的。
/* A编译单元。*/ union number;
/* B编译单元。*/ union number {int x; double y;};
/* C编译单元。*/ union number {double x; double y;};
/* D编译单元。*/ union realNumber {int x; double y;};
由于标记不同,A编译单元、B编译单元、C编译单元的联合类型与D编译单元内的联合类型是不兼容的。A编译单元内的联合类型与B编译单元、C编译单元内的联合类型是兼容的;A编译单元内的联合类型是不完整类型,B编译单元、C编译单元内的联合类型都是完整类型,在标记相同的情况下,不完整类型与完整类型是兼容的。B编译单元内的联合类型与C编译单元内的联合类型是不兼容的,它们都是完整类型,要求联合成员一一对应,联合成员的类型也要求是兼容的。