兼容类型(四)
③ 枚举的兼容性
在同一编译单元内,每个枚举都是一个新类型,与其它枚举既不相同,也不兼容。
enum {RED, GREEN, BLUE, WHITE}; enum {CLUB, DIAMOND, HEART, SPADE}; enum number {ZERO, ONE, TWO, THREE};
上述3个枚举类型尽管其枚举常量的值是相同的,但这3个枚举类型是不同的,相互之间也是不兼容的。
如果枚举说明符是先前定义的枚举类型,则该类型与先前定义的枚举类型是相同的类型。相同枚举类型都是兼容的。
enum {RED, GREEN, BLUE, WHITE} a, b; enum number {ZERO, ONE, TWO, THREE} c; enum number d;
枚举变量a、b的类型是相同的,也是兼容的;枚举变量c、d的类型是相同的,也是兼容的。
根据ISO/IEC 9899:2018标准第6.7.2.2 Enumeration specifiers节,每个枚举类型都应与char类型、有符号整数类型或者无符号整数类型兼容,具体与哪个类型兼容将由实现定义;但兼容类型应能表示所有枚举成员值。实现中编译器可能要到所有枚举常量值都明确了,才确定枚举类型与哪个类型兼容。
enum {RED, GREEN, BLUE = -10, WHITE} a; enum {CLUB, DIAMOND, HEART, SPADE} b;
使用Code::Blocks编译时,枚举变量a的类型与signed类型兼容;枚举变量b的类型与unsigned类型兼容。使用Pelles C编译时,枚举变量a、b的类型都与signed类型兼容。
在不同的编译单元中声明的两个枚举类型如果是兼容的,应满足下述条件:
- 如果一个枚举类型有标记(tag),另一个枚举类型应具有相同的标记;
- 如果两个枚举类型都是完整类型,枚举成员应该一一对应,具体包括:枚举成员的类型应该是兼容的;枚举成员数、枚举成员名、枚举成员值应该是相同的;如果存在对齐说明符,应具有等价的对齐说明符。
/* A编译单元。*/ enum shape;
/* B编译单元。*/ enum shape {CLUB, DIAMOND, HEART, SPADE};
/* C编译单元。*/ enum shape {CLUB, DIAMOND = 5, HEART, SPADE};
/* D编译单元。*/ enum number {ZERO, ONE, TWO, THREE};
由于标记不同,A编译单元、B编译单元、C编译单元的枚举类型与D编译单元内的枚举类型是不兼容的。A编译单元内的枚举类型与B编译单元、C编译单元内的枚举类型是兼容的;A编译单元内的枚举类型是不完整类型,B编译单元、C编译单元内的枚举类型都是完整类型,在标记相同的情况下,不完整类型与完整类型是兼容的。B编译单元内的枚举类型与C编译单元内的枚举类型是不兼容的,它们都是完整类型,要求枚举成员一一对应,枚举成员的值应该是相同的。