在C中溢出枚举类型?

时间:2015-05-23 03:45:45

标签: c enums integer-overflow

如果我有枚举类型,例如:

enum week{ sunday=0, monday, tuesday, wednesday, thursday, friday, saturday};

我有:

enum week day;
day = saturday;
day++;

一天的价值是什么?

3 个答案:

答案 0 :(得分:3)

枚举类型本质上是一个命名的整数值。枚举类型与可以表示所有命名值的基础整数类型相关联。该底层整数类型需要能够表示所有唯一的命名值,但其实际类型是实现定义。

在这种情况下,saturday的数值将为6。递增它将给出7的数值。实际上,这不太可能溢出底层整数类型(intcharunsigned char或编译器选择的任何内容类型,因此使用%d格式打印值将打印7

但是,没有enum week类型的枚举(命名)值,其值为7

如果递增枚举值会溢出底层整数类型(这不是这里的情况),结果是未定义的。这是因为底层整数类型可能是有符号或无符号的,溢出有符号整数类型会给出未定义的行为。

理论上,编译器可能会使用enum week的基础类型,它只能代表06的值 - 在这种情况下,递增saturday会给出char未定义的行为。在实践中,AFAIK还没有任何C编译器不选择基础类型作为标准整数类型之一(intunsigned charunsigned,{{1等等)。所有这些类型都可以表示7的数值。

答案 1 :(得分:1)

我只能找到C89规范的草稿,而且我没有C专家,所以我可能会误解它。但其章节3.5.2.2表示

  

枚举器列表中的标识符声明为具有的常量   输入int并且可以出现在允许的任何地方。 [...]每个列举   type应与整数类型兼容。

我认为这意味着$.getScript( "http://www.external_site.com/widget.js").done( function(data, textStatus, jqxhr) { $('.result').find('br').remove(); }); 此处将始终产生day++(比7所代表的值多一个。)

答案 2 :(得分:1)

假设:

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,因此类型charunsigned charsigned char必须没有填充位,每个字符类型的范围必须至少覆盖0127。更宽的整数类型(shortint等)的范围至少与signed charunsigned char的范围一样宽。因此,与enum week兼容的实现定义类型的下限不得大于0,上限不得小于127

警告:遵循语言律师。)可能存在允许扩展整数类型的漏洞,其范围比_Bool更宽,但更窄范围比char。例如,我认为是一个大小为8位的扩展整数类型,但只有3个值位是合法的。但由于需要使用整数类型来表示二进制表示,因此具有3个值位的无符号类型将能够表示0到7之间的值,而具有2个值位的无符号类型将无法表示{{1 }}。由于saturday可以包含值enum week,因此它还必须能够保存值6。在一个不寻常的实现中,可能无法表示值7,但您不太可能遇到这样的实现。

基本上,鉴于要求整数类型使用纯二进制表示,任何可以表示8的类型也可以表示6,尽管它不会自动遵循它也可以表示7