如果我有一个enum类型,如:
enum week{ sunday=0, monday, tuesday, wednesday, thursday, friday, saturday};
和我有:
enum week day;
day = saturday;
day++;
day的值是多少?
枚举类型本质上是命名整型值。该枚举类型与可以表示所有命名值的底层整型相关联。底层的整型需要能够表示所有唯一的命名值,但它的实际类型是实现定义的。
在此例中,saturday
的数值为6
。增加它将得到7
的数值。实际上,这不大可能溢出底层的整型(int
、char
、unsigned char
或编译器选择的任何类型),因此使用%d
格式打印值将打印7
。
但是,没有enum week
类型的枚举(命名)值为7
。
如果增加枚举值会溢出底层整型(这里不是这种情况),则结果是未定义的。这是因为底层的整型可以是有符号的也可以是无符号的,溢出有符号的整型会产生未定义的行为。
从理论上讲,编译器可能会使用enum week
的底层类型,该类型只能表示0
到6
的值,在这种情况下,增加saturday
会产生未定义的行为。在实践中,我敢说,还没有任何C编译器不选择底层类型作为标准整型(char
, int
, unsigned char
, unsigned
等)之一。所有这些类型都可以表示7
的数值
给定:
enum week {
sunday=0, monday, tuesday, wednesday, thursday, friday, saturday
};
enum week day = saturday;
day ++;
day
的值为7
。
引用2011 ISO C标准,6.7.2.2第1段:
每个枚举类型必须兼容
char
,一个有符号的整数类型,或无符号整数类型。类型的选择是实现定义的,但应能够表示枚举中所有成员的值。
_Bool
是一个无符号整数类型,但是它不满足这个特定枚举类型的要求。
由于CHAR_BIT
的值要求至少为8
,并且char
、unsigned char
和signed char
类型要求没有填充位,因此每种字符类型的范围必须至少覆盖0
到127
。更宽的整数类型(short
, int
等)的取值范围至少与signed char
或unsigned char
一样宽。因此,与enum week
兼容的实现定义类型的下界必须不大于0
,上界必须不小于127
。
(WARNING: Language-lawyering following .)可能存在一个漏洞,允许扩展的整数类型具有比_Bool
更宽的范围,但比char
更窄的范围。例如,我认为是一个扩展的整数类型,其大小为8位,但只有3个值位是合法的。但是由于整数类型需要使用二进制表示,具有3个值位的无符号类型将能够表示从0到7的值,而具有2个值位的无符号类型将无法表示saturday
的值。因为enum week
可以保存值6
,所以它也必须能够保存值7
。在一个不寻常的实现中,它可能不能表示值8
,但是您不太可能遇到这样的实现。
基本上,给定整数类型使用纯二进制表示的要求,任何可以表示6
的类型也可以表示7
,尽管它并不能自动推导出它也可以表示8
。
我只能找到C89规范的草案,我不是C语言专家,所以我可能会误解它。但是它的3.5.2.2节说
枚举器列表中的标识符被声明为具有的常量在允许的地方输入int和。[…]每个被列举的类型必须与整型兼容。
我认为这意味着day++
在这里总是会产生7
(比saturday
所代表的值多一个)。