当前位置: C语言 -- 专题 -- 兼容类型

兼容类型(三)

四、结构、联合、枚举的兼容性

① 结构的兼容性

在同一编译单元内,每个结构都是一个新类型,与其它结构类型既不相同,也不兼容。

struct {int age; char *name;} a;
struct {int age; char *name;} b;
struct student {int age; char *name;} c;

结构变量abc的类型是不相同的,也是不兼容的。尽管ab的类型看上去一样,但它们依然是不同的类型。


如果两个结构变量的类型相同,则这两个结构变量的类型是兼容的。如果结构变量的类型是先前定义的结构类型,则其类型与先前定义的结构类型是相同类型。相同类型一定是兼容类型。

struct {int age; char *name;} a, b;
struct student {int age; char *name;} c;
struct student d;

结构变量ab的类型是相同的,也是兼容的;结构变量cd的类型是相同的,也是兼容的。


在不同的编译单元中声明的两个结构类型如果是兼容的,应满足下述条件:

如果一个结构类型有标记(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;

联合变量abc的类型是不相同的,也是不兼容的。尽管ab的类型看上去一模一样,但它们依然是不同的类型。


如果类型说明符是先前定义的联合类型,则该类型与先前定义的联合类型是相同的类型。相同联合类型都是兼容的。

union {int x; double y;} a, b;
union number {int x; double y;} c;
union number d;

联合变量ab的类型是相同的,也是兼容的;联合变量cd的类型是相同的,也是兼容的。


在不同的编译单元中声明的两个联合类型如果是兼容的,应满足下述条件:

如果一个联合类型有标记(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编译单元内的联合类型是不兼容的,它们都是完整类型,要求联合成员一一对应,联合成员的类型也要求是兼容的。