[英]Overflow of an enum type in C?
如果我有枚举类型,例如:
enum week{ sunday=0, monday, tuesday, wednesday, thursday, friday, saturday};
我有:
enum week day;
day = saturday;
day++;
一天的价值是多少?
枚举类型本质上是一个命名的整数值。 枚举类型与可以表示所有命名值的基础整数类型相关联。 底层整数类型需要能够表示所有唯一的命名值,但其实际类型是实现定义的。
在这种情况下, saturday
的数值将是6
。 递增它将给出数值7
。 实际上,这不太可能溢出底层整数类型( int
, char
, unsigned char
或编译器选择的任何内容),因此使用%d
格式打印值将打印7
。
但是, enum week
类型的enum week
(命名)值没有值,值为7
。
如果递增枚举值会溢出底层整数类型(这不是这里的情况),结果是未定义的。 这是因为底层整数类型可以是有符号或无符号的,并且溢出有符号整数类型会给出未定义的行为。
从理论上讲,编译器可能会使用enum week
的基础类型,它只能表示0
到6
的值 - 在这种情况下,递增saturday
会给出未定义的行为。 在实践中,AFAIK还没有任何C编译器不选择基础类型作为标准整数类型之一( char
, int
, unsigned char
, unsigned
等)。 所有这些类型都可以表示7
的数值。
我只能找到C89规范的草稿,而且我不是C专家,所以我可能会误解它。 但其第3.5.2.2节说明了这一点
枚举器列表中的标识符声明为具有int类型的常量,并且可以出现在允许的位置。 [...]每个枚举类型应与整数类型兼容。
我认为这意味着day++
总会在这里产生7
(比saturday
代表的值多一个)。
鉴于:
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
。
( 警告 :随后是语言律师。)可能存在一个漏洞,允许扩展的整数类型 ,其范围比_Bool
更宽,但范围比char
更窄。 例如,我认为一个大小为8位但只有3位值的扩展整数类型是合法的。 但由于需要使用整数类型来表示二进制表示,因此具有3个值位的无符号类型将能够表示0到7的值,而具有2个值位的无符号类型将无法表示saturday
的值。 由于enum week
可以保持值6
,因此它还必须能够保持值7
。 在一个不寻常的实现中,它可能无法表示值8
,但您不太可能遇到这样的实现。
基本上,考虑到整数类型使用纯二进制表示的要求,任何可以表示6
类型也可以表示7
,尽管它不会自动遵循它也可以表示8
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.