简体   繁体   English

在C中溢出枚举类型?

[英]Overflow of an enum type in C?

If I have an enum type, like: 如果我有枚举类型,例如:

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

and I have: 我有:

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

What will be the value of day? 一天的价值是多少?

An enumerated type is essentially a named integral value. 枚举类型本质上是一个命名的整数值。 That enumerated type is associated with an underlying integral type that can represent all the named values. 枚举类型与可以表示所有命名值的基础整数类型相关联。 That underlying integral type is required to be able to represent all the unique named values, but its actual type is implementation defined. 底层整数类型需要能够表示所有唯一的命名值,但其实际类型是实现定义的。

In this case, the numeric value of saturday will be 6 . 在这种情况下, saturday的数值将是6 Incrementing it will give the numeric value of 7 . 递增它将给出数值7 In practice, that is unlikely to overflow the underlying integral type ( int , char , unsigned char , or whatever the compiler chooses), so printing the value using the %d format will print 7 . 实际上,这不太可能溢出底层整数类型( intcharunsigned char或编译器选择的任何内容),因此使用%d格式打印值将打印7

However, there is no enumerated (named) value of type enum week with a value of 7 . 但是, enum week类型的enum week (命名)值没有值,值为7

If incrementing an enumerated value would overflow the underlying integral type (which is not the case here) the result is undefined. 如果递增枚举值会溢出底层整数类型(这不是这里的情况),结果是未定义的。 This is because the underlying integral type may be signed or unsigned, and overflowing a signed integral type gives undefined behaviour. 这是因为底层整数类型可以是有符号或无符号的,并且溢出有符号整数类型会给出未定义的行为。

Theoretically, it is possible that a compiler may use an underlying type for enum week that can only represent the values 0 to 6 - in which case incrementing saturday gives undefined behaviour. 从理论上讲,编译器可能会使用enum week的基础类型,它只能表示06的值 - 在这种情况下,递增saturday会给出未定义的行为。 In practice, AFAIK, there has yet to be any C compiler which does not choose an underlying type to be one of the standard integral types ( char , int , unsigned char , unsigned , etc). 在实践中,AFAIK还没有任何C编译器不选择基础类型作为标准整数类型之一( charintunsigned charunsigned等)。 All of those types can represent the numeric value of 7 . 所有这些类型都可以表示7的数值。

I was only able to find a draft of the C89 specification, and I'm no C expert, so I might be misunderstanding it. 我只能找到C89规范的草稿,而且我不是C专家,所以我可能会误解它。 But its section 3.5.2.2 says that 但其第3.5.2.2节说明了这一点

The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted. 枚举器列表中的标识符声明为具有int类型的常量,并且可以出现在允许的位置。 [...] Each enumerated type shall be compatible with an integer type. [...]每个枚举类型应与整数类型兼容。

I think that means that day++ will always yield 7 here (one more than the value represented by saturday ). 我认为这意味着day++总会在这里产生7 (比saturday代表的值多一个)。

Given: 鉴于:

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

the value of day is 7 . day的价值是7

Quoting the 2011 ISO C standard, 6.7.2.2 paragraph 1: 引用2011 ISO C标准,6.7.2.2第1段:

Each enumerated type shall be compatible with char , a signed integer type, or an unsigned integer type. 每个枚举类型应与char ,有符号整数类型或无符号整数类型兼容。 The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration. 类型的选择是实现定义的,但应能够表示枚举的所有成员的值。

_Bool is an unsigned integer type, but it doesn't meet the requirements for this particular enumeration type. _Bool是无符号整数类型,但它不符合此特定枚举类型的要求。

Since the value of CHAR_BIT is required to be at least 8 , and the types char , unsigned char , and signed char are required to have no padding bits, the range of each of the character types must cover at least 0 through 127 . 由于CHAR_BIT的值必须至少为8 ,并且charunsigned charsigned char类型不需要填充位,因此每种字符类型的范围必须至少涵盖0127 Wider integer types ( short , int , etc.) have ranges at least as wide as that of signed char or unsigned char . 更宽的整数类型( shortint等)的范围至少与signed charunsigned char范围一样宽。 Therefore the implementation-defined type that is compatible with enum week must have a lower bound no greater than 0 , and an upper bound no less than 127 . 因此,与enum week兼容的实现定义类型必须具有不大于0的下限,并且上限不小于127

( WARNING : Language-lawyering follows.) There might be a loophole that allows for extended integer types with a wider range than _Bool but a narrower range than char . 警告 :随后是语言律师。)可能存在一个漏洞,允许扩展的整数类型 ,其范围比_Bool更宽,但范围比char更窄。 For example, I think an extended integer type with a size of 8 bits but only 3 value bits would be legal. 例如,我认为一个大小为8位但只有3位值的扩展整数类型是合法的。 But since integer types are required to use a binary representation, an unsigned type with 3 value bits would be able to represent values from 0 to 7, and an unsigned type with 2 value bits would not be able to represent the value of saturday . 但由于需要使用整数类型来表示二进制表示,因此具有3个值位的无符号类型将能够表示0到7的值,而具有2个值位的无符号类型将无法表示saturday的值。 Since an enum week can hold the value 6 , it must also be able to hold the value 7 . 由于enum week可以保持值6 ,因此它还必须能够保持值7 In an unusual implementation it might not be able to represent the value 8 , but you're unlikely encounter such an implementation. 在一个不寻常的实现中,它可能无法表示值8 ,但您不太可能遇到这样的实现。

Basically, given the requirement that integer types use a pure binary representation, any type that can represent 6 can also represent 7 , though it doesn't automatically follow that it can also represent 8 . 基本上,考虑到整数类型使用纯二进制表示的要求,任何可以表示6类型也可以表示7 ,尽管它不会自动遵循它也可以表示8

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM